melanchall / drywetmidi

.NET library to read, write, process MIDI files and to work with MIDI devices
https://melanchall.github.io/drywetmidi
MIT License
540 stars 75 forks source link

Unity cannot exit after use #276

Closed ZengRunMing closed 11 months ago

ZengRunMing commented 11 months ago

Hello, I am playing Midi files on Unity using DryWetMidi version 7.0.1.

A problem occurred. When calling Application. Quit() or closing the Unity editor after playing the Midi file, the program cannot exit. The specific situation is that the task manager displays no response, and the program can be closed only after the task manager ends the task.

melanchall commented 11 months ago

Hi,

Please read this first – https://melanchall.github.io/drywetmidi/articles/dev/Support.html. At least, provide your code. How you setup a file's playback, how you dispose devices and playback and so on.

ZengRunMing commented 11 months ago

The core code is as follows (Github does not allow files with the suffix cs) MidiControl.txt

melanchall commented 11 months ago
  1. Are you sure you properly dispose all the DryWetMIDI API when exiting Unity? Can you show where you call disposing methods?
  2. What if you comment input device creation? Is Unity still hang on exit?
  3. What if you comment playback creation? Is Unity still hang on exit?
ZengRunMing commented 11 months ago

The processing code is as follows MCL is MidiControl PB is Playback MDO is OutputDevice

private void OnApplicationQuit() { if (MCL != null && MCL[0] != null) { MCL[0].DisposeMidiOutDevice(PB, MDO); MCL[0].DisposeMidiInDevice(MDI); } MDO.Dispose(); PB.Dispose(); }

melanchall commented 11 months ago

In addition to two question you didn't provide answers on (I still need answers), I have a couple of new ones.

MCL is MidiControl MCL[0]

How you can use [0] on the MidiControl class? There is no an indexer within the class or you didn't show it. I see in your previously sent file and can't understand how you can use the [0] syntax on MidiControl. Maybe MCL is a collection of MidiControl instances? If yes, why MCL[0]? There is always only one item in the MCL? Where you dispose MCL[1], MCL[2] and so on?

Can you set breakpoint on OnApplicationQuit and confirm it's called before Unity hangs?

ZengRunMing commented 11 months ago

When I only use 'input and output', I can exit the program, but as long as I use 'playback', I cannot exit the program. MCL is a collection of MidiControl arrays, currently only MCL [0] is valid, and other array objects are not instantiated. I confirm that all object handling codes in the above code have been called before the program exits.

melanchall commented 11 months ago

Hmm, well, what if you change this code:

Playback playback = MF.GetPlayback();

to this one:

Playback playback = MF.GetPlayback(new PlaybackSettings
{
    ClockSettings = new MidiClockSettings
    {
        CreateTickGeneratorCallback = () => new RegularPrecisionTickGenerator()
    }
});

Does the Unity exit correctly now?

Also please say what version of Unity do you use?

ZengRunMing commented 11 months ago

Problem solved, Unity can exit now

The version used is 2023.3.171f1c1

melanchall commented 11 months ago

@ZengRunMing Can you please say, what helped? RegularPrecisionTickGenerator?

ZengRunMing commented 11 months ago

According to the code you provided, MidiControl has been modified and Unity can now exit normally

Playback playback = MF.GetPlayback(new PlaybackSettings
{
ClockSettings = new MidiClockSettings
{
CreateTickGeneratorCallback = () => new RegularPrecisionTickGenerator()
}
});