Search Unity

  1. Good news ✨ We have more Unite Now videos available for you to watch on-demand! Come check them out and ask our experts any questions!
    Dismiss Notice

Midi Player Tool Kit - New functions, better accuracy

Discussion in 'Made With Unity' started by BachmannT, Apr 14, 2018.

  1. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Yes, I confirm there is strange behaviors. I need more time to understand. I take you inform.
     
  2. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello
    Good news, the issue has been identified. The bad news is that the correction is not simple, I need some time to make a full test.
    A new version is quite ready, I will publish it before making important change. So the correction could be available to end of september. Is it correct for you ?
    BR
     
  3. BasicallyGames

    BasicallyGames

    Joined:
    Aug 31, 2018
    Posts:
    36
    Yeah, no rush! Thanks for working on a fix. I'll just work around the issue by recording a WAV of the music and using that until the issue has been resolved.
     
  4. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello
    Finally, the fix was not so hard to implement, so I have added it to the version 2.84:

    Version 2.84 on the way :)
    • Now switching between Midi playing is immediate.
    • Add functions to facilitate integration with Bolt [Pro]
    • Start and Stop playing gradually (ramp-up) [Pro].
    • Now Midi play also with Time.timeScale = 0.
    • And globally, a lot of enhancements on the demos (7 for free, 6 more with the pro version).
     
  5. Jezeus

    Jezeus

    Joined:
    Sep 27, 2018
    Posts:
    6
    Hi,
    Is there a way to be notified when there is a rest going on (whatever the rest size) ? there are events for notes on and off but I cannot find any for rests. I need to display a score, and computing the rest duration in between notes off and on is not sufficient, there is missing data, the resulting score cannot always be equal to the reference midi. Even when parsing with MidiLoad, cannot have the rest information.
    Thanks in advance for the advice !
     
    Last edited: Sep 10, 2020
  6. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello, what is a rest ?
     
  7. Jezeus

    Jezeus

    Joined:
    Sep 27, 2018
    Posts:
    6
  8. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    ok, I understand ! Sorry, i'm quite bad in english.
    'rest' don't exists in midi norm :https://discussions.apple.com/thread/6517602. So you can't have event of type rest.
    You have to deduce it from TimeSignature and the other notes event, if there is a hole in the tick count ... there is a rest !

    Perhaps, you could have the need of these API with MPTK:

    MPTK_NumberBeatsMeasure

    int MPTK_NumberBeatsMeasure
    From TimeSignature event: The numerator counts the number of beats in a measure. For example a numerator of 4 means that each bar contains four beats. This is important to know because usually the first beat of each bar has extra emphasis. http://www.deluge.co/?q=midi-tempo-bpm

    MPTK_TimeSigNumerator
    int MPTK_TimeSigNumerator
    From TimeSignature event: The numerator counts the number of beats in a measure. For example a numerator of 4 means that each bar contains four beats. This is important to know because usually the first beat of each bar has extra emphasis. In MIDI the denominator value is stored in a special format. i.e. the real denominator = 2^[dd] http://www.deluge.co/?q=midi-tempo-bpm

    BR
    Thierry
     
  9. Jezeus

    Jezeus

    Joined:
    Sep 27, 2018
    Posts:
    6
    Hi again ! Many thanks for this reply. It's amazingly true, there is no rest in midi, must be computed, knowing there are multiple solutions for a rest ... anyways, not your fault ! Thanks for the links, I will do it this way, do not have a choice. But I must tell you that I am unable to open these links (same goes for the ones in your source code), I always have these errors:
    Fatal error: Only variables can be passed by reference in /homepages/23/d181601631/htdocs/Drupal7/sites/all/modules/commerce/modules/cart/commerce_cart.module on line 1164

    Thanks again for your time.
     
  10. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    ok thank to inform me. I will update the doc!
    Please, don't hesitate to let a comment on the Unity store, it's very important to stay alive!
    All my best
    Thierry
     
  11. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    366
    Hi! Does this asset work in the background on both android an ios?
     
  12. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello
    Yes!
     
  13. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Sorry, I was short in time to answer more in detail. To play in background, we need two processes: the Midi Reader and the Synthesizer. These two process are running out of the main Unity Thread, so they are working in autonomous from Unity. What you done on Unity don't interfere with the player and the synth. Obviously, if heavy CPU is need for Unity, that could have an impact to the Midi player. But it's another story!
     
    justtime likes this.
  14. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    366
    Thanks for explanation! Could you specify which demo scene i can use for test? I used "TestMidiPlayer" for android build and it doesn't work in background.
     
  15. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Try the demo scene TestMidiFilePlayer.
    Perhaps, I did'nt understood your question. Could you be more precise by "background" ? Is playing Midi is not stopped when smartphone app is on background ?
     
  16. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    366
    Sorry, i tried TestMidiFilePlayer. By background I mean when app is on background, so i can use another app for example (not just another from UI thread) That is "Is playing Midi is not stopped when smartphone app is on background".
     
  17. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    By default, no.
    Application is paused on Android and iOS when app is send to background.
    Perhaps, there is a solution with background service ...
    Please take me inform if you get some result!!!
    Best regards
     
    justtime likes this.
  18. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    366
    Thanks for feedback! Work in background possible with different sound library, for example BASS. They also have midi possibilities.
     
  19. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Have you tested with BASS ?
     
  20. justtime

    justtime

    Joined:
    Oct 6, 2013
    Posts:
    366
    Now, because i don't know how your asset works, but i will certainly investigate it.
     
  21. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Dear Bachmann-san,

    Thank you for your support by email a few days ago. This time, I'm asking you here, because sharing the info is helpful for to beginners like me.

    From your TestMidiStream.cs, I want to set different instruments to different channels, as
    channel 1 for patch 40 (violin)
    channel 2 for patch 14 (Tubler Bells).

    So I wrote below. Now channel 1 is OK (Tubler Bells). But channel 0 is Piano.
    What is wrong with this?

    if (!midiStreamPlayer.OnEventSynthStarted.HasEvent()){
    CurrentPreset = 40;
    StreamChannel = 0;
    midiStreamPlayer.OnEventSynthStarted.AddListener(EndLoadingSynth);
    CurrentPreset = 14;
    StreamChannel = 1;
    midiStreamPlayer.OnEventSynthStarted.AddListener(EndLoadingSynth);
    }
    ------------------------------
    // Modify PlayOneNote
    private void PlayOneNote(int note, int velocity, int channel)

    -------------------------------
    PlayOneNote(CurrentNote, 80, 0);
    PlayOneNote(CurrentNote, 80, 1);
     
    Last edited: Sep 19, 2020
  22. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello Mister
    First of all, thank for your appreciation in the Unity store, it's always very appreciable and encouraging.

    For your question, I will answer more later with a full example. Just for now, OnEventSynthStarted is not the good method to change the preset. Let me some time to put a good answer!
    Best Regards
    Thierry
     
  23. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Thank you for your support. I'll wait.

    Regards,
    MathComposer
    Kazuo
     
  24. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Sorry for the delay. I wanted to build a short example.
    The method to use for changing preset if MPTK_ChannelPresetChange. The method must be called after the synthesizer is initialized. So we used the event OnEventSynthStarted to call EndLoadingSynth in the script.
    Try this code in your script:

    Code (CSharp):
    1.  
    2. void Start()
    3. {
    4.             if (midiStreamPlayer != null)
    5.             {
    6.                 // The call of this methods can also be defined in the prefab MidiStreamPlayer from the Unity editor inspector.
    7.                 // See "On Event Synth Started.
    8.                 // EndLoadingSynth will be called when the synthesizer will be ready.
    9.                 if (!midiStreamPlayer.OnEventSynthStarted.HasEvent())
    10.                     midiStreamPlayer.OnEventSynthStarted.AddListener(EndLoadingSynth);
    11.             }
    12.             else
    13.                 Debug.LogWarning("midiStreamPlayer is not defined. Check in Unity editor inspector of this gameComponent");
    14. }
    15.  
    16. /// <summary>
    17. /// This methods is run when the synthesizer is ready.
    18. /// It's a good place to set some synth parameter's as defined preset by channel
    19. /// </summary>
    20. /// <param name="name"></param>
    21. public void EndLoadingSynth(string name)
    22. {
    23.             Debug.LogFormat($"Synth {name} is loaded");
    24.  
    25.             // Set music box (preset 10) to channel 0. Could be different for another SoundFont.
    26.             midiStreamPlayer.MPTK_ChannelPresetChange(0, 10);
    27.             Debug.LogFormat($"Preset {midiStreamPlayer.MPTK_ChannelPresetGetName(0)} defined on channel 0");
    28.  
    29.             // Set reed organ (preset 20) to channel 1. Could be different for another SoundFont.
    30.             midiStreamPlayer.MPTK_ChannelPresetChange(1, 20);
    31.             Debug.LogFormat($"Preset {midiStreamPlayer.MPTK_ChannelPresetGetName(1)} defined on channel 1");
    32. }
    33.  
    PS: i updated the demo TestMidiStream to be more clear on this subject. That was not so obvious.

    Thierry
     
  25. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Now it worked well.
    I really appreciate your support.

    Regards,
    kazuo
     
  26. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    A few questions on TestMidiWriter.cs.

    Hello, Bachmann-san,

    Helped by your TestMidiStream.cs, I completed conversion of one of my program from Python to Unity, and now I'm adding Midi file saving function. So, let me ask a few small questions on TestMidiWriter.cs.

    (1) Just confirmation. In your tool. Midi channel is from 0 to 15. But for Writer, channel is 1 to 16. (Your set 1 for channel 0 in the file). Probably that is due to NAudio.Midi, right?

    (2) For MPTK_AddEvent (other than playing notes), you set absoluteTime++.
    Why you add ++? Same timing (just using absoluteTime without++) doesn't work well? (Sorry I didn't test.)

    Regards,
    Kazuo
     
  27. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello Kazuo
    I need to look at this demo. I writed it a long time ago! and go back to you with answers.
    Thierry
     
  28. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello Kazuo
    (1) Yes channel is from 1 to 16. It's not consistent with other MPTK API. I apologize for that. I will perhaps change this in a next version.
    (2) I can't remenber why i used absoluteTime++.!!! perhaps to control in the Midi generated ... So, useless, for sure.

    Best Regards
    Thierry
     
  29. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Bachmann-san,

    Than you for sharing your time. Well Understood.

    Regards,
    Kazuo
     
  30. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Only one Drum note played by MidiStreamPlayer

    Thank you for your support. This is a bit more serious question.
    By MidiStreamPlayer, I can't play more than one drum note at the same timing.
    How can I play Bass_drum, Snare and Hihat at the same time?

    Based on your TestMidiStream.cs
    -------------------------------
    // Modify PlayOneNote as
    private void PlayOneNote(int note, int velocity, int channel)

    -------------------------------
    Notes (e.g. Piano) below can play at the same time.
    PlayOneNote(60, 80, 0); // note C4 channel 0
    PlayOneNote(64, 80, 0); // note E4 channel 0

    But, drum notes below cannot play at the same time and only the last note plays. Why and How can I fix this?
    PlayOneNote(36, 80, 9); // Bass_drum channel 9
    PlayOneNote(42, 80, 9); // Closed Hihat channel 9
     
  31. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello Kazuo
    try this before playing notes:
    midiStreamPlayer.MPTK_KillByExclusiveClass = false;
    if it correct your issue, I will explain!

    Best regards
    Thierry
     
  32. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Bachmann-san,

    It worked well. Thank you.

    Best Regards,
    Kazuo
     
  33. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Some explanation:
    Kill By Exclusive Class: the default behavior of a Midi synthesizer is to released a note when a note of the same class is played in the same preset. The Class (a number) is defined in the SoundFont. Generally, this function is used by drum kit: a cymbal will kill other drum instrument.

    Currently, this parameter is available only in the prefab inspector of MidiFilePlayer or by script. With the next version it will be available in other MPTK prefab.

    Best Regards
    Thierry
     
  34. MathComposer

    MathComposer

    Joined:
    Sep 18, 2020
    Posts:
    8
    Thank you for your kind explanation.
    Understood. I really appreciate your support.

    Best Regards,
    Kazuo
     
  35. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    I like have talk about MPTK, it's always interesting; so thank to you!
    I created a post about SoundFont exclusive classes here

    Have Fun !
     
  36. djidane535

    djidane535

    Joined:
    Jun 19, 2016
    Posts:
    3
    Hi!

    Thanks for your hard work on this library. It fills exactly a need I had for making rythm games based on MIDI files. I have just one regret about it at the moment: the lack of support for WebGL engine.

    I started to participate to a few game jams, and I know it's very important to have a WebGL version of the game. Before buying the Pro version, is there any plan to make it compatible? (is it possible or are there any major missing components preventing it?).

    Thanks in advance.
     
  37. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    161
    Hello
    Thanks for your interest with MPTK.
    Sadly, there is no solution for WebGL with its current version. Mainly, the issues is WebGL platform does not support threads,so it's not possible ...
    Sorry.
    All My Best
    Thierry
     
  38. djidane535

    djidane535

    Joined:
    Jun 19, 2016
    Posts:
    3
    Thanks for your honest answer.
     
unityunity