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.
  2. Join us on March 30, 2023, between 5 am & 1 pm EST, in the Performance Profiling Dev Blitz Day 2023 - Q&A forum and Discord where you can connect with our teams behind the Memory and CPU Profilers.
    Dismiss Notice

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:
    352
    Which version are you using ?
    Pro or Free ?
    Could you check the sound font setup: you need to have a default bank selected for instrument and drum (even if you have only one bank).
    upload_2021-8-22_21-7-22.png

    Thierry
     
  2. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    I'm using Pro version. My custom soundfont only has 2 banks: Bank 0 for instruments and bank 127 for drums. Somehow, MPTK_ChannelForcedPreset is looking for bank -1 or bank 1. It doesn't always happen but will be problematic when it happens in the middle of game because it will not change the preset for the channel.
     
  3. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    I can't find any reason you get bank -1 or 1. Could you explain more in detail this sentence above ? why do you speak about MidiFilePlayer ?
     
  4. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Don't you need MidiFilePlayer to play midi on MidiStreamPlayer? I'm using MidiStreamPlayer because I need to be able to change notes value to make specific channel to be vals. MPTK_ChannelForcedPreset is always looking at the correct bank for MidiFilePlayer but not for MidiStreamPlayer.
     
  5. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Do I need MidiStreamPlayer to play altered MPTKEvent or will MidiFilePlayer itself is enough?
     
  6. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    MidiStreamPlayer and MidiFilePlayer are totally independent.
    • MidiStream: playing music you create in real time by script
    • MidiFile: playing music from MIDI file you import.
    The two objects are based on the same synth software: class MidiSynth (so, MPTK_ChannelForcedPreset is available for the two) but the synths play independently (object are instancied), as if you have two distinct physical synthesizer. The change on one don't impact the second.

    But you can used the two (as with real synths linked with a MIDI cable). For example in the demo CatchMusic, the MidiFIlePlayer reads MIDI events but not play it (Send To Synth is disabled)

    upload_2021-8-23_7-29-58.png

    MIDI events are read with OnEventNotesMidi.AddListener(NotesToPlay). The callback NotesToPlay create 3D objects which hold the MIDI info. See MusicView.cs
    When 3D object falls, the MIDI event carried is played with a MidiStreamPlayer see NoteView.cs and ControlView.cs
    In the demo the MIDI info (so, the music) are modified in some case before played:

    // If original z is not the same, the value will be changed
    int delta = (int)(zOriginal - transform.position.z);
    note.Value += delta; // change the original note
    // Now play the note with a MidiStreamPlayer prefab
    midiStreamPlayer.MPTK_PlayEvent(note);

    Last point: As seen MidiStreamPlayer and MidiFIlePlayer are independent but they share the same SoundFont!
    I hope that can help you!

    All my best
    Thierry
     
  7. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Is there a way for MPTK_ChannelPresetChange not to get overwritten when MidiFilePlayer first played? Something like MPTK_ChannelForcedPresetSet but you can select which bank that you wanted to switch to. I tried using MPTK_SelectBankInstrument to the target bank but it didn't work. It works with MPTK_ChannelPresetChange but only if MidiFilePlayer is already playing.
     
  8. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    No, the channel information is clear when a MIDI is started
     
  9. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
  10. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    You can use this event:
    midiFilePlayer.OnEventStartPlayMidi.AddListener(StartPlay);

    StartPlay will be call each time a MIDI is start to play.

    /// <summary>
    /// Event fired by MidiFilePlayer when a midi is started (set by Editor in MidiFilePlayer Inspector or by script see above)
    /// </summary>
    public void StartPlay(string name)
    {
    // example, change the start position
    // Could works also with MPTK_ChannelPresetChange
    if (StartPositionPct > 0f)
    midiFilePlayer.MPTK_TickCurrent = (long)((float)midiFilePlayer.MPTK_TickLast * (StartPositionPct / 100f));
    }
     
  11. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Hi, is there a function to get total times played on a channel? For instance, I wanted to know how many times channel 1 is played on my midi.
     
  12. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    I just read about MPTK_ChannelInfo in the documentation here, but I can't access that function in MidiFilePlayer. Was it removed?
     
  13. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Also can you get the list of TrackMidiEvent of a midi before playing it? If I tried to do:

    foreach (var note in midiFilePlayer.MPTK_MidiEvents)
    {
    Debug.Log(note.Event);
    }

    before playing it, it returns null reference.
     
  14. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Sorry! The site has been updated too earlier, that will be available with the next version 2.89.1 in one or two week.
     
    Last edited: Sep 6, 2021
  15. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Yes you can, but the MIDI must be loaded before or you can use the prefab MidiFileLoader https://paxstellar.fr/prefab-midifileloader/
     
  16. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Or use a event OnEventStartPlayMidi
    https://mptkapi.paxstellar.com/d7/d...player.html#ae65eea39e3fb3b6ea8f6f9adaa2a631f


    MidiFilePlayer midiFilePlayer;
    void Start()
    {
    // Get a reference to the prefab MidiFilePlayer from the hierarchy in the scene

    midiFilePlayer = FindObjectOfType<MidiFilePlayer>();

    // Add a listener on the MIDI File Player.
    midiFilePlayer.OnEventStartPlayMidi.AddListener(StartPlay);
    }

    public void StartPlay(string midiname)
    {
    // then something like that ... read midi event to a List<>

    List<MPTKEvent> mptkEvents = midiFilePlayer.MPTK_ReadMidiEvents();
    }
     
  17. dadi_victorious

    dadi_victorious

    Joined:
    Sep 8, 2021
    Posts:
    2
    Hi...
    I'm having problems with the MPTK volume.. looks like a channel/track that plays more than one note (2 or more) like chord shapes together, the volume of the channel is louder than the channel/track that plays a single note..

    I do midi balancing using synthfont, I also set midi cc for volume automation, pan, and others. and it sounds fine. but in mptk it sounds very different.

    how to solve this..?
     
  18. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello
    Really strange, there is no relation between the final loud of the sounds and channels: all samples of all channels are mixed in the same left/right buffer. It's a fluidsynth behaviour and I think also for a lot of wave tables synths.
    Is it possible to get a demo of this issue ? video, script, MIDI, ....
     
  19. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Hello, how do I access pan info of a MPTKEvent? I tried it like this, but the log result is still the value of the midi note.
    upload_2021-9-9_13-56-21.png
     
  20. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Also there's some error when showing midi note value on certain midis. You can test it by making a new script and put this in Start()
    upload_2021-9-9_16-15-26.png
    and try it with midi downloaded here http://www.hamienet.com/midi33557_Dragonforce--Through-Fire-and-Flames.html

    Sometimes, it shows the value as >9000. As far as I know, that's not possible as midi note value is limited in range of 0-127.
     
    Alvare32 likes this.
  21. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello
    I loaded your MIDI and added a log for MIDI note value greater than 127, and nothing has been log.
    See also the log for the pan change message. 0=left, 64=center, 127=right
    upload_2021-9-10_18-22-26.png

    and the script to display these logs:
    Code (CSharp):
    1.      
    2. /// <summary>
    3. /// Event fired by MidiFilePlayer when midi notes are available.
    4. /// Set by Unity Editor in MidiFilePlayer Inspector or by script with OnEventNotesMidi.
    5. /// </summary>
    6. public void MidiReadEvents(List<MPTKEvent> midiEvents)
    7. {
    8.         foreach (MPTKEvent midiEvent in midiEvents)
    9.         {
    10.                 switch (midiEvent.Command)
    11.                 {
    12.                     case MPTKCommand.ControlChange:
    13.                         // Log pan message
    14.                         if (midiEvent.Controller == MPTKController.Pan)
    15.                             Debug.LogFormat($"Pan Channel:{midiEvent.Channel} Value:{midiEvent.Value}");
    16.                         break;
    17.  
    18.                     case MPTKCommand.NoteOn:
    19.                         if (midiEvent.Value > 127)
    20.                             Debug.LogFormat($"Note Channel:{midiEvent.Channel} {midiEvent.Value} Velocity:{midiEvent.Velocity} Duration:{midiEvent.Duration}");
    21.                         break;
    22.               }
    23.        }
    24. }
    25.  
    Regards
    Thierry
     
    Last edited: Sep 10, 2021
  22. Alvare32

    Alvare32

    Joined:
    May 26, 2020
    Posts:
    54
    MPTK_SearchMidiToPlay and MPTK_SelectSoundFont are gone after updating. Could you please tell me which functionality has replaced these?
    Oh lol. I think I got the free version once again from package manager. Very annoying issue on Unity's part, not the assets fault.

    EDIT - I updated by going into my AppData/Roaming/Unity folder and everything's working flawlessly now once more. And even better, it seems that playback has improved as well from the version I used before. This asset remains a gem! :D
     
    Last edited: Sep 12, 2021
  23. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Good to know, thank for the tip!
     
    Alvare32 likes this.
  24. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Tried it with this code
    upload_2021-9-13_9-32-56.png
    I got value >8000 around tick 60000. Could you check it with the code above? I'm afraid I'm the only one with this problem.
     
  25. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Ok so adding the switch to MPTKEvent command returns the correct value. But with the code you've provided, I only debug the pan value on midi start only. How do I always debug the pan value of each MPTKEvent?
     
  26. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    See my previous script and screenshot!
     
  27. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    Yes, I used that script and it only logs the first note played but not the rest unless I'm missing a step here.
    upload_2021-9-13_12-42-38.png
    upload_2021-9-13_12-42-54.png
    upload_2021-9-13_12-44-9.png
    The log stops here.
     

    Attached Files:

  28. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Sorry, these screenshot can't help me.
    What would be even better, if you care to take the time, is a test project, where you use the assets and the error occurs. Would that be possible for you? I will be able to analyse more in detail your issue.
    All my best
    Thierry
     
  29. GroveJr

    GroveJr

    Joined:
    Nov 15, 2019
    Posts:
    17
    I've sent an email containing the example project package.
     
  30. dadi_victorious

    dadi_victorious

    Joined:
    Sep 8, 2021
    Posts:
    2
    can you give me a recommendation which midi editor software is good for midi production?
    because I feel there is a difference between each midi editor. so which one do you think is the most appropriate or the one with the closest result to MPTK?
     
  31. Kish8475

    Kish8475

    Joined:
    Dec 21, 2020
    Posts:
    2
    Hi. Unity for Oboe seems to have updated. Maybe it's "callback" separates data and error callback.
     
  32. Kish8475

    Kish8475

    Joined:
    Dec 21, 2020
    Posts:
    2
    Unity for Oboe → Oboe for Unity
     
  33. autumn602177136

    autumn602177136

    Joined:
    Aug 30, 2021
    Posts:
    1
    Can you give me some advice on how to implement portamento on MPTK?It seems that the portamento event is not working now
     
  34. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello,
    Sorry for this late answer, it seems that the forum notification is broken :-(
    All MIDI editors will work perfectly with MPTK. On my side I like cakewalk ...
     
  35. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello,
    Sorry for this late answer, it seems that the forum notification is broken :-(
    I see that, have you an issue ?
     
  36. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello,
    Sorry for this late answer, it seems that the forum notification is broken :-(
    Also, I apologise but Control Change portamento is not implemented.
    I did'nt found mlidi with this CC. Have you one ?

    Thierry
     
  37. Alvare32

    Alvare32

    Joined:
    May 26, 2020
    Posts:
    54
    Hello there,
    I've been trying to get a popup list to return all songs in the midiplayerglobal during editor mode, not runtime. However, this only works when the component of midifileplayer is opened in the inspector. Often, it seems that the instance isn't there so it returns an null reference exception error message instead.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEditor;
    3. using MidiPlayerTK;
    4. using System.Collections.Generic;
    5.  
    6. public class SongStart : MonoBehaviour, ISerializationCallbackReceiver
    7. {
    8.     public static List<string> SongList;
    9.     [HideInInspector] public List<string> PopupList;
    10.     [ListToPopup(typeof(SongStart), "SongList")]
    11.     [SerializeField] public string selectedSong;
    12.     private List<string> MidiFilesList;
    13.     private void OnEnable()
    14.     {
    15.         if (Game.Instance == null) return;
    16.         if (Music.currentSongPlaying != selectedSong)
    17.         {
    18.             Game.Instance.GetMusicController.RoamingInOverworld(selectedSong);
    19.             Game.Instance.GetMusicController.StartMusic(selectedSong);
    20.         }
    21.     }
    22.     public List<string> Read()
    23.     {
    24.         List<string> AllSongs = new List<string>();
    25.         foreach (string songname in MidiPlayerGlobal.CurrentMidiSet.MidiFiles)
    26.         {
    27.             AllSongs.Add(songname);
    28.         }
    29.         return AllSongs;
    30.     }
    31.     #if UNITY_EDITOR
    32.     public void OnBeforeSerialize()
    33.     {
    34.         MidiFilesList = new List<string>();
    35.         MidiFilesList = MidiPlayerGlobal.CurrentMidiSet.MidiFiles;
    36.         if (MidiFilesList == null) return;
    37.         PopupList = Read();
    38.         SongList = PopupList;
    39.     }
    40.  
    41.     public void OnAfterDeserialize() { }
    42.     #endif
    43. }
    Is there any other way to get a list during editor mode?
    Preferably, I'd like the popup list to be identical to the one is the midiplayerloader component so I can easily overview all songs without having to scroll down.
    Thanks in advance!
     

    Attached Files:

    • Test.jpg
      Test.jpg
      File size:
      407.3 KB
      Views:
      190
  38. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello

    I think the issue is that some init are mandatory in edit mode:

    Code (CSharp):
    1. MidiPlayerGlobal.InitPath();
    2. ToolsEditor.LoadMidiSet();
    3. ToolsEditor.CheckMidiSet();
    You could get inspiration from this script MidiPlayer\Scripts\Editor\MidiFileLoaderEditor.cs
    It's the script for the MidiFileLoader inspector, so you will find how loading and displaying the list of MIDIs.
    Search winSelectMidi in the code which instanciate the popup (from SelectMidiWindow class)

    Regards
    Thierry
     
  39. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Also get inspiration from this this script MidiPlayer\Scripts\Editor\SelectMidiWindow.cs
    to build a popup similar as from the inspector.
    Thierry
     
  40. Alvare32

    Alvare32

    Joined:
    May 26, 2020
    Posts:
    54
    Huh.. that's strange.
    I cannot reach both ToolsEditor and SelectMidiWindow classes from within my script for some unknown reason.
    Even when I'm using the same namespace MidiPlayerTK. o_O
     

    Attached Files:

    • Huh.jpg
      Huh.jpg
      File size:
      253.3 KB
      Views:
      200
    • Huh2.jpg
      Huh2.jpg
      File size:
      242.7 KB
      Views:
      196
    Last edited: Oct 28, 2021
  41. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    It's because these two classes are available only for the editor project.
    The script which used them must be in an editor folder.
    upload_2021-10-28_15-41-19.png

    Thierry
     
  42. Alvare32

    Alvare32

    Joined:
    May 26, 2020
    Posts:
    54
    But dragging the current script into the editor folder makes it unable to be added onto an gameObject.
    Honestly, this is mind boggling concept to me. Does that mean my class need to inherit from some sort of editor class to be able to read from ToolsEditor and SelectMidiWindow alongside being a monobehaviour that can be added to the insepctor?
     
  43. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    If you do this you will not be able to generate an application outside the unity editor !
     
  44. Alvare32

    Alvare32

    Joined:
    May 26, 2020
    Posts:
    54
    Ah I see. I shouldn't be doing that then. xD
     
  45. Alvare32

    Alvare32

    Joined:
    May 26, 2020
    Posts:
    54
    Spend hours scratching my head over this. Isn't there a way to just read directly from the directory instead? I have no clue whatsoever to get editor scripts working. :confused:
    EDIT - Did this instead:

    Code (CSharp):
    1.     public List<string> Read()
    2.     {
    3.         List<string> AllSongs = new List<string>();
    4.  
    5.         DirectoryInfo dir = new DirectoryInfo("Assets/MidiPlayer/Resources/MidiDB");
    6.         FileInfo[] info = dir.GetFiles("*.*");
    7.         foreach (FileInfo f in info)
    8.         {
    9.             if (!f.Name.Contains(".meta"))
    10.             {
    11.                 string filename = f.Name;
    12.                 var newStr = filename.Replace(".bytes","");
    13.                 filename = newStr;
    14.                 AllSongs.Add(filename);
    15.             }
    16.         }
    17.         return AllSongs;
    18.     }
     
    Last edited: Oct 28, 2021
  46. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello,
    Sorry for this late answer, really the forum notification is broken :-(

    This approach will not work outside the Unity editor. These resources files will be packaged in a unity resource file. You will not be able to read them.

    Rather look at the demo TestMidiFileLoad how to use the method MPTK_ListMidi

    Code (CSharp):
    1.  
    2. // Display popup in first to avoid activate other layout behind
    3.  PopMidi.Draw(MidiPlayerGlobal.MPTK_ListMidi, MidiIndex, myStyle);
    4.  
    and here the doc

    Regards
    Thierry
     
    Alvare32 likes this.
  47. franMx

    franMx

    Joined:
    May 27, 2013
    Posts:
    30
    Hi, is there a barebones example on how to use MidiStreamPlayer?
    I currently have a prefab with the component as well as :
    Code (CSharp):
    1.    
    2. public MidiStreamPlayer midiStreamPlayer; //reference to prefab
    3.  
    4. void Start()
    5. {
    6.     PlayOneNote();
    7. }
    8.  
    9. private void PlayOneNote()
    10.     {
    11.         Debug.Log("i will play..");
    12.         // Play a note C5 for 1 second on the channel 0
    13.         NotePlaying = new MPTKEvent()
    14.         {
    15.             Command = MPTKCommand.NoteOn,
    16.             Value = 60,  //C5
    17.             Channel = 0,
    18.             Duration = (long)1000f,
    19.             Velocity = 110,
    20.             Delay = (long)0f,
    21.         };
    22.         midiStreamPlayer.MPTK_PlayEvent(NotePlaying);
    23.         Debug.Log("end of i will play..");
    24.     }
    But I get: Maestro Error Object reference not set to an instance of an object

    Thanks
     
  48. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hello
    Do you have set midiStreamPlayer from your inspector or from the script ?
    Otherwise midiStreamPlayer stay .. null. Must be set with the prefab MidiStreamPlayer added in your scene.
    upload_2021-11-11_20-45-46.png

    There is a lot of demos with MidiStreamPlayer prefab. For example TestMidiStream.

    Some information here: https://paxstellar.fr/midi-file-player-detailed-view-2-2/
    regards
    Thierry
     
  49. franMx

    franMx

    Joined:
    May 27, 2013
    Posts:
    30
    Hi, thanks a lot. I'm kind of puzzled, as I already have the MidiStreamPlayer assigned in the inspector. I tried to modify the TestMidiStream example scene, using a script similar to the one of the documentation, with no luck getting it to work, so most likely I'm missing something simple but can't determine what is it.
     
  50. BachmannT

    BachmannT

    Joined:
    Nov 20, 2016
    Posts:
    352
    Hi
    Could you build a package (without any resource) I will have a look.

    Also, I have updated the page about the Prefab MidiStreamPlayer
    I hope this is more clear,say me!
     
    Last edited: Nov 14, 2021