Jump to content

Convert MIDI to JS to use inside Scripter?


Danny Wyatt

Recommended Posts

Is there a way (hopefully not too complex) to convert MIDI notes into JS that can be pasted into Scripter and when we press a note (C1, for example) it triggers those notes? For example something like this:

image.png.c29891299478a9c241580801c431abcd.png

 

I found this website that converts MIDI to JSON, I don't know if this could be somehow useful? Maybe some of the information there could be used?
https://tonejs.github.io/Midi/

 

@Dewdman42 I believe you are probably the best person to answer this question?

Link to comment
Share on other sites

Yes its possible for sure to playback midi from Scripter.  However I will not have time to work on it.

I did something similar to this in the past, which I have pointed you to before, you can have a look here:

https://gitlab.com/dewdman42/MainstageMidiPlayer/-/wikis/home

Look specifically at the script there called MidiPlayer.js.  MidiPlayer.js doesn't use json.  It uses midicsv format.  But you can see how a midifile can be played back in Scripter as you wish.  You would have to modify the script to playback when you press a midi key.  

If you want to use that json format for the midi then you would have to re-write a lot of the script to do that instead of parsing the midicsv.   Parsing json is much easier then parsing midicsv.  I chose midicsv at the time for a couple reasons, for one thing I didn't know about the site you mentioned, which is kind of interesting.  But for another thing, midicsv has been around for decades and will continue to be around for a very long time.  The site you mentioned, while cool, is just someone else's idea about representing a midi file as json, but it may or may not exist tomorrow or the next day as a website that can generate the json.  

One thing you'll have to figure out is how you would want script to respond to a midi key to playback.  Should it start the sequence at the next beat boundary, or play it back starting immediately, even if you hit the key ahead or behind of a beat?  I would recommend you kind of have to quantize that action so that it would start at the next beat.   I haven't looked at this script in some time, that is definitely doable, but I'm not sure if and when I would have time to help you figure that part out.

 

Edited by Dewdman42
  • Like 1
Link to comment
Share on other sites

1 hour ago, David Nahmani said:

Note that if you wanted an easier way to accomplish this you can look into Touch Tracks: https://support.apple.com/en-gb/guide/logicpro/lgcp7e2a503e/mac

Thanks for sharing. Unfortunately, this is not what I'm looking for. My goal is to have a way to create and save MIDI sequences as presets so I can quickly load them with the previous and next buttons. I will check it anyway, just out of curiosity to see what it does.

Link to comment
Share on other sites

1 hour ago, Dewdman42 said:

Yes its possible for sure to playback midi from Scripter.  However I will not have time to work on it.

I did something similar to this in the past, which I have pointed you to before, you can have a look here:

https://gitlab.com/dewdman42/MainstageMidiPlayer/-/wikis/home

Look specifically at the script there called MidiPlayer.js.  MidiPlayer.js doesn't use json.  It uses midicsv format.  But you can see how a midifile can be played back in Scripter as you wish.  You would have to modify the script to playback when you press a midi key.  

If you want to use that json format for the midi then you would have to re-write a lot of the script to do that instead of parsing the midicsv.   Parsing json is much easier then parsing midicsv.  I chose midicsv at the time for a couple reasons, for one thing I didn't know about the site you mentioned, which is kind of interesting.  But for another thing, midicsv has been around for decades and will continue to be around for a very long time.  The site you mentioned, while cool, is just someone else's idea about representing a midi file as json, but it may or may not exist tomorrow or the next day as a website that can generate the json.  

One thing you'll have to figure out is how you would want script to respond to a midi key to playback.  Should it start the sequence at the next beat boundary, or play it back starting immediately, even if you hit the key ahead or behind of a beat?  I would recommend you kind of have to quantize that action so that it would start at the next beat.   I haven't looked at this script in some time, that is definitely doable, but I'm not sure if and when I would have time to help you figure that part out.

This seems like a very complex process. I wanted to create something that others can just simply convert a MIDI file into some kind of file where they could copy it, then paste it into Scripter and have it work. If they have to install extra things they are probably not familiar with (such as installing homebrew and all that), then it's not what I'm looking for. I was just wondering if there was a simple way to just copy-paste-use it.

I'm in the process of hiring someone to create this plugin and sell it, but I wanted to know if I was able to first do something with the tools Logic offers. Apparently, it doesn't (not in an easy way, anyway).

Thanks for sharing that info, though!

Edited by Danny Wyatt
Link to comment
Share on other sites

that's what mine does.  If you want to do it another way you can use my code as an example to get you started for coding your own.

The thing you want to do is not going to be an easy or simple script.  If you're not up for the complexity, then I suggest you look for a third party product that does something like this for you, but I don't know of anything that does.

Link to comment
Share on other sites

1 minute ago, Dewdman42 said:

that's what mine does

From what I read on that page, you need to install homebrew, right? Then you mention "midicsv", which I don't know what it is. I was checking their website, but it seems very complex. As I mentioned, I want to be able to provide a product that the most "basic" people can use without installing anything. They export the MIDI File, drag that MIDI file somewhere to convert to a certain type of text, then paste that text into Scripter, but it can't replace everything there, because I need a transpose feature available if they want to transpose it. So it's more complex than that. I will go find a developer that can build it from scratch. I either provide a Scripter solution, or a new plugin that they purchase and use out of the box.

Link to comment
Share on other sites

I would suggest you explore with it and learn.

Yes, the easiest way to get midicsv is to install homebrew, which is a handy thing to have installed on your Mac anyway.  There are all sorts of useful command line utilities that can be installed via homebrew.  midicsv is also a fairly useful little utility because you can quickly and easily inspect the contents of a  midifile with it.

If you don't want to use midicsv or homebrew, then just look at the script I did and learn how it works, and re-write it to use the json midi you would rather use.  I actually originally wrote that MidiPlayer.js using json also, but later switched to using midicsv because I feel its a more "standardized" format.

 

Edited by Dewdman42
  • Like 1
Link to comment
Share on other sites

ps - if you're wanting to provide something for other people to use, that I don't recommend Scripter at all.  As you can see, you are not interested in using what I did with scripter...that's because its not an easy problem to solve with Scripter...and you will find the same thing.  If you want something other people can use, then you should write something in C++.

Edited by Dewdman42
Link to comment
Share on other sites

1 minute ago, Dewdman42 said:

re-write it to use the json midi you would rather use

When I shared that website, my goal was not to "force" the use of json files, because I have no idea what those are. I shared that website, because the info there could be (or not) be useful when converting files. So it's not that I have a preference, because I really. don't know how midi files or json files work when it comes to Javascript compatibility. It was just something I found.

 

2 minutes ago, Dewdman42 said:

homebrew, which is a handy thing to have installed on your Mac anyway

Yes, but again, not everyone who's just a normal Logic user to record basic things, will find the need to install homebrew, especially if they have no idea how to do it or what it does. I'm not talking about more "advanced" users. I'm talking regular people with simple demands. I don't want to put too much on their place. I want something as simple as possible.

Link to comment
Share on other sites

7 minutes ago, Dewdman42 said:

if you're wanting to provide something for other people to use, that I don't recommend Scripter at all

What I was trying to understand was if it was possible to do something like this:
Lines of code "A"
Lines of code "B" (this would be the MIDI information itself)
Lines of code "C"

When someone wants to create a new preset, they would replace B with something else, resulting in this:
Lines of code "A"
Lines of code "M" (this would be the MIDI information itself for another sequence)
Lines of code "C"

So yeah, it's not possible. I will find someone with C++ knowledge instead.
Thanks for clarifying!

Edited by Danny Wyatt
Link to comment
Share on other sites

2 hours ago, Dewdman42 said:

play it back starting immediately, even if you hit the key ahead or behind of a beat

yes, this would play the file when the person plays the note so it's up to them to record or place the note where they want it to play

Edited by Danny Wyatt
Link to comment
Share on other sites

Regarding JSON vs Midicsv, here is a small midi file converted to JSON format (with the site you linked) and midcsv for comparison.  In either case you need script that can parse that format...then someone would copy and paste either the midicsv for the json...into the right spot in the script and have playback working.  That's the best you can do with Scripter.

here is a short little midi file with three notes, converted to midicsv and json for comparison.  

midicsv:

0, 0, Header, 0, 1, 480
1, 0, Start_track
1, 0, Channel_prefix, 0
1, 0, Title_t, "Inst 1"
1, 0, Instrument_name_t, "Inst 1"
1, 0, Time_signature, 4, 2, 24, 8
1, 0, Key_signature, 0, "major"
1, 0, SMPTE_offset, 97, 0, 0, 0, 0
1, 0, Tempo, 500000
1, 0, Note_on_c, 0, 60, 80
1, 120, Note_off_c, 0, 60, 64
1, 120, Note_on_c, 0, 62, 80
1, 240, Note_off_c, 0, 62, 64
1, 240, Note_on_c, 0, 64, 80
1, 360, Note_off_c, 0, 64, 64
1, 21120, End_track
0, 0, End_of_file

JSON:

{
  "header": {
    "keySignatures": [
      {
        "key": "C",
        "scale": "major",
        "ticks": 0
      }
    ],
    "meta": [],
    "name": "Inst 1",
    "ppq": 480,
    "tempos": [
      {
        "bpm": 120,
        "ticks": 0
      }
    ],
    "timeSignatures": [
      {
        "ticks": 0,
        "timeSignature": [
          4,
          4
        ],
        "measures": 0
      }
    ]
  },
  "tracks": [
    {
      "channel": 0,
      "controlChanges": {},
      "pitchBends": [],
      "instrument": {
        "family": "piano",
        "number": 0,
        "name": "acoustic grand piano"
      },
      "name": "Inst 1",
      "notes": [
        {
          "duration": 0.125,
          "durationTicks": 120,
          "midi": 60,
          "name": "C4",
          "ticks": 0,
          "time": 0,
          "velocity": 0.6299212598425197
        },
        {
          "duration": 0.125,
          "durationTicks": 120,
          "midi": 62,
          "name": "D4",
          "ticks": 120,
          "time": 0.125,
          "velocity": 0.6299212598425197
        },
        {
          "duration": 0.125,
          "durationTicks": 120,
          "midi": 64,
          "name": "E4",
          "ticks": 240,
          "time": 0.25,
          "velocity": 0.6299212598425197
        }
      ],
      "endOfTrackTicks": 21120
    }
  ]
}

 

Link to comment
Share on other sites

8 minutes ago, Danny Wyatt said:

What I was trying to understand was if it was possible to do something like this:
Lines of code "A"
Lines of code "B" (this would be the MIDI information itself)
Lines of code "C"

When someone wants to create a new preset, they would replace B with something else, resulting in this:
Lines of code "A"
Lines of code "M" (this would be the MIDI information itself for another sequence)
Lines of code "C"

So yeah, it's not possible. I will find someone with C++ knowledge instead.
Thanks for clarifying!

As I said already, that is what my MidiPlayer.js script does.  I don't have time to customize it for you, but if you have a look at it and learn how it works, you can modify it to use JSON instead of Midicsv, etc..

I originally wrote that script in order to do midifile playback from inside MainStage.  


Good luck

Edited by Dewdman42
Link to comment
Share on other sites

7 minutes ago, Dewdman42 said:

then someone would copy and paste either the midicsv for the json...into the right spot in the script and have playback working

Yes, that's what I wanted to achieve, regardless of the format (midicsv or json). My goal was to have a "template" that I would share and a section would be where they paste it, so whatever code is before and after that section, would not be affected, that way I could implement a transpose feature that would be applied to the whole sequence.

What I liked about that website is that you just drag and drop a MIDI file and it converts it to you. If the same was available for the midicsv without the need of installing additional things (homebrew for example), that would be easier.

I would be able to tell them:
Step 1: export your MIDI file
Step 2: drag and drop that file into this website
Step 3: copy that text
Step 4: open the Scripter preset that I provide
Step 5: find the section XYZ and paste the code you just copied

Done!

Link to comment
Share on other sites

13 minutes ago, Dewdman42 said:

but if you have a look at it and learn how it works, you can modify it to use JSON instead of Midicsv,

You are assuming I know enough about it to make those changes... ;)
I was looking at your file and it's WAY too complex! I have no idea what's going on there.

Never mind, I will find someone to build it from scratch.

Link to comment
Share on other sites

if you want to use my script you can modify it to use the JSON instead of midicsv, as I said.  and it already works as you are wanting, there is a section where you paste the midicsv, seperate from the actual code.  

Actually the scripts I did are even easier then that, I included there a bash script that basically can do the whole job for you, you feed it a midifile and it generates the complete working Script for you, no copy and paste of anything required....but yes, you have to install midicsv for it to work.  There are other ways to install midicsv besides using homebrew, that just happens to be the easiest way.

You could also wrap all that stuff inside an AppleScript pretty easily, where your users would simply provide a midifile...and AppleScript would automatically put a completely functioning script onto the clipboard, then your user simple pastes that into the entire scripter window.  Easy.  But they would need midicsv installed.  Or actually it might even be perfectly acceptable and allowable to actually bundle midicsv inside of an AppleScript bundle and then nobody has to install anything.    I might look into that.

 

Edited by Dewdman42
Link to comment
Share on other sites

 

9 hours ago, Dewdman42 said:

you can try this Danny.  Here is a little droplet.  Put this on your desktop or in the dockbar.  Drag a midifile onto it.  It will save the result on the clipboard.  Open Scripter and paste that as a new script into Scripter.  

No need to install homebrew nor midicsv, its built into the droplet.

mid2scripter.zip 63.96 kB · 0 downloads

Thank you for sharing. Unfortunately, it's not working:
image.png.7954bbc0df7480ef91a691b0d8dd1287.png

Link to comment
Share on other sites

10 minutes ago, Dewdman42 said:

I do t have time to fix it right now but eliminate any spaces from the midifile name and try it again 

Yes that fixed it.

15 hours ago, Dewdman42 said:

If you want to modify the behavior of the actual script used to playback (responding to midi keys, etc), then you can open up this app bundle and edit the following file

I appreciate your "faith" on my capabilities, but I believe you are assuming I'm on a level of JS knowledge that I'm not. Not even close. ;)

This whole process is way too complex for me to even wish messing with it. I appreciate your time and help with this. I will definitely be looking at having someone build me the right tool, ready to use by any person with a bunch of MIDI files.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...