Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.

Maestro Midi Player Tool Kit - Good news for your rhythm game !

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

  1. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello, have you make some progress ? need more information ?
     
  2. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
    Hi Thierry,
    I already had pro and I came across an issue about track volumes.

    Please download the zip file and play test2.mid file with MptkFilePlayer
    All tracks will be played in the same volume.

    Piano has 10% volume
    Marima has 100% volume
    Drum has 0% volume (it shouldn't play)

    Now, go to https://signal.vercel.app/edit page an import the file and play it. It plays as expected.

    Is this a bug or a problem with midi file?
    Thanks!
     

    Attached Files:

  3. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    hello
    Sure, there is something strange, I look at this more in detail and let you inform as soon as possible.
    Regards
     
  4. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello again,
    This issue is only when playing the MIDI file from the editor in the "Midi File Setup". That will be corrected with the next version. Do you need a patch in the meantime?

    I checked also when playing in run mode. There is no issue, the volume by channel is what expected.
    But could you check that "Apply Modulator" is set in the inspector ?

    upload_2022-11-1_10-34-37.png

    Regards
    Thierry
     
  5. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
    Hello Thierry,

    Thank you for quick response.
    I updated to the latest version and in fact the problem is gone for play mode (as you said). I have no urgency for editor mode.

    Thanks
    Cihad
     
  6. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
    Hi again Thierry, :)

    I have another question. Players can create midi files in my game and I use the following code:

    Code (CSharp):
    1. MidiFileWriter2 mfw = new MidiFileWriter2();
    2. // ...
    3. MidiFile midiToSave = mfw.MPTK_BuildNAudioMidi();
    4. var bytes = MidiFile.Export(midiToSave.Events);
    I somehow see the following exception on crashlytics. Any idea why?


    upload_2022-11-4_11-35-13.png
     
  7. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello, before you need to sort the MIDI, like this:
    mfw.MPTK_SortEvents();

    Regards
    Thierry
     
  8. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
    I have checked the source code. You are already doing it in `MidiFile.Export` method (See screenshot)
    Do I still need to call `mfw.MPTK_SortEvents()` ?
    upload_2022-11-5_20-4-39.png
     
  9. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Exact, you are right. Could you send me a simple extract of your script with this issue. I will test it. Thanks
     
  10. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    I confirm you need to call mfw.MPTK_SortEvents(); before.
    Have a look to the demo Assets\MidiPlayer\Scripts\Editor\MidiSequencerWindow.cs
    method:
    Code (CSharp):
    1.  
    2. private void WriteMidiSequenceToFileAndPlay(string name, MidiFileWriter2 mfw)
    3. {
    4.             // build the path + filename to the midi
    5.             string filename = Path.Combine(Application.persistentDataPath, name + ".mid");
    6.             Debug.Log("Write Midi file:" + filename);
    7.  
    8.             // Sort the events by ascending absolute time (optional)
    9.             mfw.MPTK_SortEvents();
    10.             mfw.MPTK_Debug();
    11.  
    12.             // Write the MIDI file
    13.             mfw.MPTK_WriteToFile(filename);
    14.  
    15.            // ...
    16. }
    17.  
     
  11. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
    Oh thank you very much @BachmannT
    I'm releasing an update with SortEvents function today and let you know if there is any exceptions thrown.
     
  12. Napsta

    Napsta

    Joined:
    Sep 16, 2020
    Posts:
    2
    Hello!

    I'm working on a musical compositional rpg. I'm trying to proof of concept currently by simply loading a midi and adjusting values in live time.

    Currently I cannot figure out how to play through my List<MPTKEvent> that I've loaded through the midiFileLoader. I know I need to use midiStreamPlayer but all the examples are just one-shot notes.

    Help is super appreciated. Thanks!
     
  13. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello, that sound very interesting! What could be a "musical compositional rpg" ?

    I will try to answer to your question.
    The midiFileLoader is just a MIDI loader, useful only to analyses the MIDI events from a MIDI file. No playing capabilities.

    For playing music by script there are two ways depending your needs:
    • Playing music you are building in real time: The prefab MidiStreamPlayer is the good choice. It take MPTKEvent for input. But you need to manage time at which each notes (or other MIDI events) must be played. Typically generated in your Update() function.
    • Playing music built by code but delayed: The class MidiFileWriter2 is a better choice (with the MPTK Pro). Ypu are able to define time for each MIDI events to be played in MIDI ticks or in milliseconds.
    See global explanation and examples in the pages above.

    Others sources are the demos available:

    upload_2022-11-15_21-16-58.png


    Have a look also to the detailed API description.
    If your need is simply loading a midi (from a MIDI file) and adjusting values in live time, you could also use the prefab MidiFilePlayer, it's "just" a MIDI player from a MIDI file but you can modifying MIDI events in real time, before they are played.
    Thanks to the OnMidiEvent event (MPTK Pro). The OnMidiEvent is used also in the demo "Play Midi With Script"

    upload_2022-11-15_21-32-12.png


    ... perhaps another way with a major next version, but that need a lot of works!

    Regards
    Thierry
     
  14. Napsta

    Napsta

    Joined:
    Sep 16, 2020
    Posts:
    2
    Thank you very much for such a fast response!

    I have made some progress with the help from your post and have managed to a selected MIDI into the file loader by using:

    Code (CSharp):
    1.  
    2.  private void LoadMidi()
    3.     {
    4.         if (midiFileLoader.MPTK_Load())
    5.         {
    6.             midiSequence = midiFileLoader.MPTK_ReadMidiEvents();
    7.         }
    8.         else
    9.             Debug.Log($"Loading '{midiFileLoader.MPTK_MidiName}' - Error");
    10.     }
    11.  
    I am then executing the sequence through a coroutine as such:

    Code (CSharp):
    1.     private IEnumerator PlayWholeMidiTrack()
    2.     {
    3.         for (int i = 0; i < midiSequence.Count; i++)
    4.         {
    5.             Debug.Log(i);
    6.             midiStreamPlayer.MPTK_PlayEvent(midiSequence[i]);
    7.             yield return new WaitForSeconds(0.1f);
    8.         }
    9.     }
    Now I know you mention this: "But you need to manage time at which each notes (or other MIDI events) must be played. Typically generated in your Update() function".

    Does this mean there's no way of obtaining the note's pause data? As you can see in the coroutine, currently it just waits for 0.1 seconds and sounds very awkward.

    To answer your question about the musical compositional RPG, I'm trying to create a battle system where the player can change the key with their attacks. This is why I want to load a MIDI sequence, have it play exactly as loaded and then change it dynamically later.

    Again, thank you so much for your help! My project is for my Master's so the help is super appreciated.

    Napsta
     
  15. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    A very good idea! Could be a fun game!
    There is no "pause" in midi norm, each events MIDI Note-on contains a time to be played (attributes ticks) and another MIDI events Note-off for the time to release the note (like a pianist on a keyboard).
    MPTK create a singleMIDI event Note-on with these attributes : Ticks and RealTime (for time in millisecond) and Duration in milliseconds:
    upload_2022-11-16_2-24-30.png

    What you want to do is to re-create the internal MIDI sequencer available in MPTK, not so easy! That could work for a very simple MIDI but will be ... ankward!
    What do you mean by change the "key" ? Change the value of the note ?
     
  16. zhaojiangjiang

    zhaojiangjiang

    Joined:
    Aug 31, 2019
    Posts:
    4
    BachmannT likes this.
  17. soyfeo123

    soyfeo123

    Joined:
    Jul 31, 2020
    Posts:
    12
    really?
    no choice to add soundfonts on the free version?
     
  18. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Really no, sorry !
     
  19. xccloveny222

    xccloveny222

    Joined:
    Nov 14, 2022
    Posts:
    2
    Have you ever solve this problem?
    I met the same problem.
    Waiting for reply.
    Regards
     
  20. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello, I just ran some test with the last version of Maestro and Oboe, all works fine on my tests devices. Unluckily, I can't check for every hardware.
    On which platform have you this issue?
    Also could you check with this demo?
     
    Last edited: Dec 30, 2022
  21. a4505ab

    a4505ab

    Joined:
    Sep 25, 2022
    Posts:
    4
    I want to make a rhythm game.

    I already can produce note by midi file so far.
    And didn't make sound until note move to the specified position.
    Like this video.


    But I got a problem.

    In Unity, sound tempo is not meet midi file's BPM.
    My midi file is 170BPM.

    But Its tempo is wrong, not 170BPM.
    And And the sound rhythm is not stable. Ragged speed.

    My note moving code is here:
    Code (CSharp):
    1. using System.Collections;
    2. using System.Collections.Generic;
    3. using UnityEngine;
    4.  
    5. public class GameObjectMove : MonoBehaviour
    6. {
    7.     public static float Speed = 15f;
    8.     public float translation;
    9.     // public GameObject MusicView3;
    10.     // Start is called before the first frame update
    11.     void Start()
    12.     {
    13.         // MusicView3 = GameObject.Find("MusicView3");
    14.     }
    15.  
    16.     // Update is called once per frame
    17.     void Update()
    18.     {
    19.      
    20.     }
    21.  
    22.     void FixedUpdate()
    23.         {
    24.             // Move the note along the X axis
    25.             translation = Time.fixedDeltaTime * Speed;
    26.             transform.Translate(translation, 0, 0);
    27.         }
    28. }
    How do I fix it?
     
  22. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello,
    For the issue with the tempo, could you send your MIDI file?
    For the second question, I don't see anything related to Maestro in your code. Could you send me more details?
    Thank
     
    a4505ab likes this.
  23. a4505ab

    a4505ab

    Joined:
    Sep 25, 2022
    Posts:
    4
    Thank you.
    How do I send file to you?
    E-mail or Do you have discord server?
     
  24. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    As you want! go to the web site, you will find all contacts information.
    regards
     
  25. xccloveny222

    xccloveny222

    Joined:
    Nov 14, 2022
    Posts:
    2
    Galaxy S21 with android 11.I have tested your new demos,and they all sounded weird.If you can borrow one form anyone of your friends, that will be show you directly。
     
  26. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
    Hey @BachmannT,
    Another small question...
    Is there a way to change event data (eg. change note value) in `OnEventNotesMidi` callback?

    When I checked the code, it was possible in legacy version. Isn't it possible now with core mode?
    Thanks
     
  27. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
  28. cihadturhan_unity

    cihadturhan_unity

    Joined:
    Apr 19, 2021
    Posts:
    37
  29. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello, another approach would be to use the two methods!

    • OnMidiEvent (run in a dedicated thread): able to change the MIDI events in real time before they are playing. This can be done also in relation with your app. All static data in your application can be used if they are updated by your Unity Update() loop in parallel.
    • OnEventNotesMidi (run in the Unity thread): to change what you want in your Unity scene.

    Regards
    Thierry
     
    cihadturhan_unity likes this.
  30. NyuBlara

    NyuBlara

    Joined:
    Feb 17, 2022
    Posts:
    2
    Hello,

    I am a student working on a mobile (Android) implementation of a project called the MidiFilePerformer. To put it simply, it consists in a user being able to replay a MIDI file in a simple rhythmic fashion without knowing how to play music.

    Now, for technical reasons in this project (i.e. needing to consider notes separated only by a few milliseconds as simultaneous), I need to be able to convert the entirety of the events' ticks to milliseconds. This, of course, is a fairly well-known algorithm (using the header TicksPerQuarter resolution and the tempo events strung along the MIDI file) but I was wondering if something similar already exists in the library to save me the work of copy-pasting and adapting my old code, written to do this job.

    To try and clarify, the process would look something like this :

    - Look through the List<MPTKEvent> obtained via the MidiFileLoader's ReadMidiFile() method,
    - Exclude any events except for note and tempo
    - Use the last tempo event as a reference to convert the tick of each note.

    I was wondering if this is already part of the library somehow.

    While I'm at it, I just want to make sure : ReadMidiFile *does* return a flat list containing all events regardless of track in chronological order, right ?

    Thank you very much in advance for your help !
     
  31. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Hello,
    You have an interesting project!
    Yes, MPTK_ReadMidiEvents returns an array of all MPTKEvent ordering by time and each MPTKEvent contains the time in milliseconds of the MIDI event in relation with the tempo change.

    Regards
    Thierry
     
  32. NyuBlara

    NyuBlara

    Joined:
    Feb 17, 2022
    Posts:
    2
    Merci ! ;)

    Just to make sure, the field you're talking about is MPTKEvent.RealTime, right ?

    I might also take the chance to ask, but : do you think MidiInReader will work on an Android app ? It'd be nice if we could take input through a MIDI keyboard connected to the phone via USB.

    Thanks again!
     
  33. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    342
    Yes ! it's the attribute RealTime
    https://mptkapi.paxstellar.com/d9/d..._event.html#a39a42055ea47ddc0db185f9b10345f67

    Unluckily, MidiInreader (and especially the plugins MidiKeyboard) is not running on Android, only MacOS and Windows. Obviously, MPTK_ReadMidiEvents and RealTime will not work with a real-time MIDI interface!

    Regards
    Thierry