Euterpea / Euterpea2

Euterpea version 2

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Crash after playing any midi note on Windows

FilipNest opened this issue · comments

Found the HSoM book in a bookshop today and was intrigued so bought it, and after hours of trying to get anything to run I'm close to giving up.

I've got to the point of a MIDI note playing but either GHCi or compiled files crash as soon as one note plays. Anything after a single note (or chord) doesn't play as the system crashes back to a prompt (and back out of GHCi). There are no warnings, logs or other messages and the inital midi note on is certainly sent. devices lists devices fine and doesn't crash. So I suspect things are installed correctly but something about the midi system is crashing. I've output both to windows default midi and a virtual midi port and get the same results. A single message is sent / sound is played and then it dies.

There's this section in the troubleshooting section which seems similar:

(Windows MIDI playback) Calling the “play” function on any Music value crashes GHCi. 

This can happen with the 64-bit versions of Haskell Platform on pre-creators update Windows 10 and on any version of Windows with Haskell Platform 8.0.1 or earlier. For older versions of Windows and/or older versions of  Haskell Platform, please use the 32-bit version on Windows if you want to work within GHCi. Alternatively, try compiling your program to an executable with GHC.

But I've tried various versions of GHC (downgrading it to match what's in the docs) and compiling it and it's always the same. I'm on Windows 11 which I hope this is possible to get running on.

Anyone who can offer any troubleshooting help or modern advice on how to get this running would be greatly appreciated as it'd be sad if the book just gets put on a shelf / binned and never used as was intrigued being both a composer and a programmer with some haskell knowledge.

I don't have access to Windows 11 to do any direct testing unfortunately. A couple things that might help in trying to narrow down the issue here:

  • Does playS on a finite value (like "c 4 qn") do the same thing? The playback backends for play and playS are somewhat different.
  • Can you export a MIDI file of the Music value with writeMidi?
  • What exactly do you see listed when you run "devices"?

What a delightfully quick response!

  • playS is a bit better than play as playS (c 4 hn :+: c 5 hn) gets to the second note for a tiny moment and then glitches out and crashes. (EDIT: Playing shorter durations actually gets to a third note sometimes. It's like it can only run for a short moment of time before crashing.)
  • I can export! This is amazing and makes the library actually useful even if I can't directly trigger / play things. I've written even a long line of notes to a file, popped it into a midi player and it plays fine.
  • the devices command gives me:
Input devices:
  InputDeviceID 1       01. Ethernet MIDI

Output devices:
  OutputDeviceID 0      Microsoft MIDI Mapper
  OutputDeviceID 2      Microsoft GS Wavetable Synth
  OutputDeviceID 3      01. Ethernet MIDI

I'm in the UK and I've already stayed up until 2am on this so will sensibly pop to bed now and try again tomorrow. Thanks again for responding so quickly and getting me excited about this again.

Hmm...I have read a couple of unrelated reports of the GS Wavetable Synth (which is all MIDI Mapper directs to) being problematic on Windows 11. Something I'd like to look into if I can get access to a Win11 machine at some point. Did it do the same thing with the Ethernet MIDI device?

For the immediate future, using writeMidi and only doing finite Music values is what I'd fall back on. So, if you ever build an infinite structure, just be sure to do this when you export it:

Say you have...
infMusic = c 4 qn :+: infMusic
then within GHCi, export it as...
writeMidi "out.mid" (cut 8 infMusic)
where 8 is however many measures (in 4/4; there's no notion of tempo/timesig for this) of music you want to output.

The main other downside to using writeMidi as a workaround is that you won't be able to use the Musicla User Interfaces (MUIs) to do real-time, GUI-controlled MIDI I/O with the HSoM library.

The only other thing I could suggest is to give CoolSoft VirtualMIDISynth a try (which I gather is fully Win11 compatible), look up its device number after install and reboot using the "devices" function again, and then try using playDev to output to that synth.

Could you also send me the exact ghc version you're using and the package versions listed by doing a "ghc-pkg list"? This would let me check if it's possibly a dependency version thing (although it may not be, and even if it is, it might take me a while to test properly).

Thanks!

I don't think it's a problem with the specific synthesiser as the Virtual Midi Synth (plugged into an external device) plays a note fine then crashes before note off (same as others), as does CoolSoft VirtualMIDISynth. So I don't think this is at the device level but something before.

ghc-pkg list gives me

 C:\ghcup\ghc\8.10.5\lib\package.conf.d
    Cabal-3.2.1.0
    Win32-2.6.1.0
    array-0.5.4.0
    base-4.14.2.0
    binary-0.8.8.0
    bytestring-0.10.12.0
    containers-0.6.4.1
    deepseq-1.4.4.0
    directory-1.3.6.0
    exceptions-0.10.4
    filepath-1.4.2.1
    (ghc-8.10.5)
    ghc-boot-8.10.5
    ghc-boot-th-8.10.5
    ghc-compact-0.1.0.0
    ghc-heap-8.10.5
    ghc-prim-0.6.1
    ghci-8.10.5
    haskeline-0.8.0.1
    hpc-0.6.1.0
    integer-gmp-1.0.3.0
    libiserv-8.10.5
    mtl-2.2.2
    parsec-3.1.14.0
    pretty-1.1.3.6
    process-1.6.9.0
    rts-1.0.1
    stm-2.5.0.1
    template-haskell-2.16.0.0
    text-1.2.4.1
    time-1.9.3
    transformers-0.5.6.2
    xhtml-3000.2.2.1

C:\Users\filip\AppData\Roaming\ghc\x86_64-mingw32-8.10.5\package.conf.d
    Euterpea-2.0.8
    HCodecs-0.5.2
    PortMidi-0.2.0.0
    QuickCheck-2.14.3
    Stream-0.4.7.2
    arrows-0.4.4.2
    fail-4.9.0.0
    heap-1.0.4
    lazysmallcheck-0.6
    random-1.2.1.2
    semigroups-0.20
    splitmix-0.1.0.5

Let me know if there's anything else I can do / run that would help troubleshoot this.

Darn...looks like one of my working installations is the same versions as what you have (plus a lot of other stuff, but that shouldn't have any bearing on this). HCodecs and PortMidi were the two things where I was really hoping to see a difference that might explaint the playback issue, but no luck there. It could yet be one of those, but perhaps a deeper issue sitting in those packages' respective dependencies that just affects Win11 (but not Win10). However, we need a test of the functionality that Euterpea uses from those without Euterpea's other stuff to confirm that. It's been a long time since I worked on Euterpea's playback module but I'll see what I can do to pull out a test of the same pipeline that basically starts at some pre-defined MIDI messages, goes through PortMidi/HCodecs, and doesn't import anything else in Euterpea.

Alright, I have a semi-stripped-down version of MidiIO uploaded here (called PMPlayback.lhs) but uses nothing else in Euterpea: https://drive.google.com/file/d/1gUWcUBbSya5N2Jo6e2HKXTJNWVDMmkYR/view?usp=drive_link
Had to put it on Google drive because it wouldn't let me attach an lhs here.
Load that file up into GHCi and run:
playTwoNotes 0
which should try to send things to MidiMapper (you can change 0 to another device if you want), and then let's see how far the printouts get.

Oh oops - one other thing; I just changed the module name to Main and added a main function and re-uploaded in case the crash is taking out GHCi altogether (so if you downloaded it before seeing this, redownload the file to get the updated version). If the issue is totally taking out GHCi, then compile PMPlayback.lhs to exe and run the exe from powershell in case the crash is covering up some useful error messages,

Thanks for continued help and that debugging file:

PMPlayBack.lhs through GHCi throws out of GHCi completely after the following:

Initializing MIDI...
Sending Note On...
Sent
Waiting briefly...
Sending Note Off...

The one note plays but note off never gets sent. Confirmed this by running the midi into a plugin on a different port and seeing the stuck note:
image

Then compile to exe and ran and sadly get the same crash, just exits before Sending Note Off.

(Just in case my system was screwed in some other way I used the mido python library to play some notes and everything works fine but that uses RtMidi now)

Based on the fact that it is apparently successful in some Win11 cases, it makes me wonder if Windows 11 is heading down a similar annoying path to Linux with PortMidi compatibility. The lack of error tells me something outside Haskell is simply not returning a value. The problem does not seem to be within Euterpea at any rate, and I'm doubtful it would be HCodecs or PortMidi either since (since NoteOn works; there's nothing special about NoteOff, it's just a different byte code and we have the same versions). I do wonder whether it has to do with the gradual evolution of Windows MIDI Services and the move to MIDI 2.0 with supposed MIDI 1.0 backwards compatibility. Often there are hiccups in such a process. I don't know for sure whether the MIDI 2.0 stuff and other updates to the MIDI Services are being delivered incrementally with Windows updates, but if it is, that would be what I would suspect at this point.

Unfortunately, this being the only instance I've ever heard of of the particular behavior in question (no errors, no warnings, just hanging) I'm not sure what else to do except to use the writeMidi fallback - which is the same thing I end up recommending to Linux folks who have ALSA/PortMidi issues. I really hope this is something that miraculously goes away with a Windows update at some point and that Win11 isn't heading down the same sort of patchy compatibility path that makes Euterpea so iffy for the many flavors of Linux.