digego / extempore

A cyber-physical programming environment
1.4k stars 127 forks source link

mplay randomly drops midi notes #355

Open jasonlevine opened 5 years ago

jasonlevine commented 5 years ago

Hi all,

I recently upgraded from 0.7.0 to HEAD and found that midi notes were being dropped constantly. It seems to happen when more than one note is played at a time. The notes that go missing appear to be completely random. When I play the same sequence of 4 note chords over and over again, different notes are missing each time. It rarely plays all four notes, but it always plays at least one note. Most of the time at notes are missing. I have used midi monitor to make sure the problem wasn't happening in my midi host. Either way, the same code in 0.7.0 never misses a midi note. Not sure how to debug this one.

Jason

benswift commented 5 years ago

Hi Jason, that's a bummer. Are you using the portmidi (which is sortof the default, or at least it's in external/ rather than contrib/) or RTMidi? The midi stuff hasn't changed in a long time - in fact I don't really think it's different between now and 0.7.0.

Which OS are you using? And if Windows, do you know which midi backend you're using?

One other thing to try as a workaround is to us a smaller --frames parameter at extempore startup - sometimes that can help. Although it's not a fix, I'll admit that.

CastixGitHub commented 4 years ago

This also happens with CC messages

as ben suggested I lowered the frames to a quarter of default, but didn't change the behaviour

doesn't happens with this example code:

(sys:load "examples/sharedsystem/midisetup.xtm")

(bind-func midi_cc
  (lambda (timestamp:i32 controller:i32 value:i32 chan:i32)
    (println "MIDI_CC :" controller value chan "timestamp:" timestamp)
    void))

gif of working example: (patchage is the thing with "wires", vbeybd the window with keyboard and slider, the upper knob is an example i'm writing) out-1

instead, if I just do (sys:load "examples/sharedsystem/setup.xtm") it receives some of the changes, but not them all (nevers gets to 0 or 1)

gif of non-working example: out-3

digego commented 4 years ago

Hi Vincenzo,

It's a little difficult to follow but it looks to me from the videos like your machine is just struggling with load. In your first video you can see that the shell printouts are very responsive. In the second video the output looks very delayed/sluggish - which indicates to me that your hardware is overwhelmed.

The question then is why. At a guess I would say it's either (a) you have some funny midi config resulting in a midi feedback loop or some such or (b) your machine just isn't coping with the sharedsystem - even with nothing running. It's very difficult to say for sure without knowing more about your setup.

One relatively easy check you could do is to replace dspmt and dsp:set! in audiosetup.xtm, with something like this:

(bind-func dspmt:DSPMT (lambda (in time chan dat) 0.0))

(dsp:set! #f dspmt)

This will take all the audio load off the system and if you're still having trouble then you've got something funny in your midi config. If everything works well with your midi then your system isn't coping with the audio load. If that is the case then we can work on ways to fix that - but one step at a time.

Maybe (or maybe not) to reassure you of what should be possible - I do what you're doing all the time, tweaking synth params using cc while running upwards of 10 analogue synths, and my midi performance is excellent

Also, don't worry about messing with frames - leave frames at 1024 unless you want lower-latency audio. Changing the default frame rate will not effect midi performance (or anything other than audio latency these days). For these performance tests definitely leave it at 1024.

If you're still having trouble and need more help can you let us know your OS, hardware specs etc..

Cheers, Andrew.

On Sat, Sep 12, 2020 at 6:04 AM Vincenzo Castiglia notifications@github.com wrote:

This also happens with CC messages

as ben suggested I lowered the frames to a quarter of default, but didn't change the behaviour

doesn't happens with this example code:

(sys:load "examples/sharedsystem/midisetup.xtm")

(bind-func midi_cc (lambda (timestamp:i32 controller:i32 value:i32 chan:i32) (println "MIDI_CC :" controller value chan "timestamp:" timestamp) void))

gif of working example: (patchage is the thing with "wires", vbeybd the window with keyboard and slider, the upper knob is an example i'm writing) [image: out-1] https://user-images.githubusercontent.com/21062669/92966165-53a79a80-f477-11ea-963d-39785f864a0e.gif

instead, if I just do (sys:load "examples/sharedsystem/setup.xtm") it receives some of the changes, but not them all (nevers gets to 0 or 1)

gif of non-working example: [image: out-3] https://user-images.githubusercontent.com/21062669/92967760-1abcf500-f47a-11ea-84ba-c1c23ea0650b.gif

PS: anyway shouldn't midi related integers be just i8 instead of i32?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/digego/extempore/issues/355#issuecomment-691288113, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEHPKOMKGRWTLDX7J3P3QTSFJ7DLANCNFSM4G3234AQ .

CastixGitHub commented 4 years ago

Thank you Andrew

It's just that the printf call prints an "outdated" value (I tried all of what you described, the mock dspmt and so on, didn't fix the issue, because it's just about print, not getting midi values (tested some audio and the value is correct, never skipped a note_on)) so if I put something like

(println)
(println  (ftod (aref MCC_ARR controller)))

just after (aset! MCC_ARR controller (/ (i32tof value) 127.0))

I see that the value I printed is right, meanwhile the one in printf is the previous one, that's why it seemed it did never reach 0 or 1 before.

how does that printf in-place work? I struggled for nothing at all :)

(referring to https://github.com/digego/extempore/blob/88a553aab0e03e5564f8f4fb2af2898da6b19cb9/examples/sharedsystem/setup.xtm#L63 this printf call)

digego commented 4 years ago

OK, that makes sense now, we need to add a flush.

On Tue, Sep 15, 2020 at 8:13 AM Vincenzo Castiglia notifications@github.com wrote:

Thank you Andrew

It's just that the printf call prints an "outdated" value (I tried all of what you described, the mock dspmt and so on, didn't fix the issue, because it's just about print, not getting midi values (tested some audio and the value is correct, never skipped a note_on)) so if I put something like

(println) (println (ftod (aref MCC_ARR controller)))

just after (aset! MCC_ARR controller (/ (i32tof value) 127.0))

I see that the value I printed is right, meanwhile the one in printf is the previous one, that's why it seemed it did never reach 0 or 1 before.

how does that printf in-place work? I struggled for nothing at all :)

(referring to https://github.com/digego/extempore/blob/88a553aab0e03e5564f8f4fb2af2898da6b19cb9/examples/sharedsystem/setup.xtm#L63 this printf call)

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/digego/extempore/issues/355#issuecomment-692341682, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAEHPKJRTRUD2VXLVYBLTRDSF2IRNANCNFSM4G3234AQ .

necrostaz commented 3 years ago

Hi I got this issue too. First I decreased frames count from 8192 to 1024 (default) and things become much better. But sometimes notes were to short or completely drops. I found that function play-midi-note from portmidi sends midi-on event and then midi-off after time equal note duration. Sometimes midi-off events overlaps midi-on events of next notes and so we have drops. So I decreased time of midi-off event for one sample and all things seems to be well now. (impc:aot:do-or-emit (define play-midi-note (lambda (time device pitch velocity duration channel) (callback time 'pm_send device *midi-note-on* channel pitch velocity) (callback (+ time (- duration 1)) 'pm_send device *midi-note-off* channel pitch velocity) )))

I know - it not a best solution, but it works for me. Hope it helps.

And I have no idea why frame count affects midi behaviour.

benswift commented 3 years ago

Thanks @necrostaz thanks for the tip---I'll have a look into it asap. What platform/OS version are you on?

necrostaz commented 3 years ago

Hi @benswift I use Win10\x64, extempore 0.8.9 (btw it would be great to add --version switch to command line) and loopMIDI driver as midi transport. Also I use external audio interface Audient id4 set to 96kHz rate and 8192 buffer, but as I said - I decrease settings to 44100 and 1024

benswift commented 3 years ago

Hey, so sorry about the long delay in replying. May 24 (the day you left your comment) was actually the day I fell down the stairs at work and dislocated & broke my elbow. I'm on the mend now, thankfully, but still not 100%.

Anyway, good to hear you've found a (sortof) workaround.

Re: the --version switch, I do agree that that would be super helpful. Wouldn't be too hard to add.