xenharmonic-devs / scale-workshop

Design and visualize microtonal scales and play them in your web browser. Export your scales for use with VST instruments. Convert Scala files to various tuning formats.
MIT License
84 stars 13 forks source link

Export Super Midi Pak jsond #363

Open SeanArchibald opened 2 years ago

SeanArchibald commented 2 years ago

Request received via email:

I was wondering if you could add an additional tuning system output for Scale Workshop. It is for Super Midi Pak, a Super Nintendo midi synth cart. https://www.supermidipak.com/ It can save the data in a json file that lists out the value of each of the 128 notes in semitones in decimals with a resolution of a ten thousandth of a semitone or four places after the decimal. Whole number values are semitones in 12 tone relative to 12 tone (I don't know if I said that right). The default value for the first semitone value for midi note 0 is 0, for note 1 it is 1, for note 2 it is 2, and so on. To make them sharp you add a number after the decimal point. So standard tuning jsond is: "custom_tunings":{"tunings":[{"semitone":0},{"semitone":1},{"semitone":2},... (no decimals)

A custom tuning would be: "custom_tunings":{"tunings":[{"semitone":0.684},{"semitone":1.6484},{"semitone":2.4256},... It only takes a positive values so to go below you would go down at least a semitone and then tune up in ten thousandth of a semitone from there.

Super Midi Pak uses a Web Midi interface for all of its functions, and alternate turning is here: https://www.supermidipak.com/app/#custom_tunings I java attached the jsond file that the web interface exports and added some random tunings starting at note 70 as a demonstration. You can do the same using the Export Session button.

Contents of attached super midi pak.json:

{"version":3,"type":"super_midi_pak_sample_uploader_session","sample_catalogue":[],"sample_directory":[],"global_settings":{"global_reg_12":127,"global_reg_28":127,"global_reg_44":0,"global_reg_60":0,"global_reg_13":60,"global_cc_90":0,"global_reg_15":127,"global_reg_31":0,"global_reg_47":0,"global_reg_63":0,"global_reg_79":0,"global_reg_95":0,"global_reg_111":0,"global_reg_127":0,"global_omni":127,"global_poly":127},"channel_settings":[{"channel_program_0":0,"channel_control_10_0":64,"channel_control_7_0":127,"channel_control_11_0":127,"channel_control_81_0":0,"channel_control_82_0":0,"channel_control_86_0":127,"channel_control_85_0":127,"channel_control_1_0":0,"channel_control_76_0":64,"channel_control_5_0":1,"channel_control_37_0":0,"channel_nrpn_1_0":0,"channel_nrpn_2_0":0,"channel_nrpn_3_0":8192,"channel_control_65_0":0,"channel_control_66_0":0,"channel_control_64_0":0,"channel_control_68_0":0,"channel_control_103_0":0,"channel_control_102_0":0,"channel_nrpn_0_0":0,"channel_control_83_0":0,"channel_control_12_0":64,"channel_control_13_0":64,"channel_control_89_0":0},{"channel_program_1":0,"channel_control_10_1":64,"channel_control_7_1":127,"channel_control_11_1":127,"channel_control_81_1":0,"channel_control_82_1":0,"channel_control_86_1":127,"channel_control_85_1":127,"channel_control_1_1":0,"channel_control_76_1":64,"channel_control_5_1":1,"channel_control_37_1":0,"channel_nrpn_1_1":0,"channel_nrpn_2_1":0,"channel_nrpn_3_1":8192,"channel_control_65_1":0,"channel_control_66_1":0,"channel_control_64_1":0,"channel_control_68_1":0,"channel_control_103_1":0,"channel_control_102_1":0,"channel_nrpn_0_1":0,"channel_control_83_1":0,"channel_control_12_1":64,"channel_control_13_1":64,"channel_control_89_1":0},{"channel_program_2":0,"channel_control_10_2":64,"channel_control_7_2":127,"channel_control_11_2":127,"channel_control_81_2":0,"channel_control_82_2":0,"channel_control_86_2":127,"channel_control_85_2":127,"channel_control_1_2":0,"channel_control_76_2":64,"channel_control_5_2":1,"channel_control_37_2":0,"channel_nrpn_1_2":0,"channel_nrpn_2_2":0,"channel_nrpn_3_2":8192,"channel_control_65_2":0,"channel_control_66_2":0,"channel_control_64_2":0,"channel_control_68_2":0,"channel_control_103_2":0,"channel_control_102_2":0,"channel_nrpn_0_2":0,"channel_control_83_2":0,"channel_control_12_2":64,"channel_control_13_2":64,"channel_control_89_2":0},{"channel_program_3":0,"channel_control_10_3":64,"channel_control_7_3":127,"channel_control_11_3":127,"channel_control_81_3":0,"channel_control_82_3":0,"channel_control_86_3":127,"channel_control_85_3":127,"channel_control_1_3":0,"channel_control_76_3":64,"channel_control_5_3":1,"channel_control_37_3":0,"channel_nrpn_1_3":0,"channel_nrpn_2_3":0,"channel_nrpn_3_3":8192,"channel_control_65_3":0,"channel_control_66_3":0,"channel_control_64_3":0,"channel_control_68_3":0,"channel_control_103_3":0,"channel_control_102_3":0,"channel_nrpn_0_3":0,"channel_control_83_3":0,"channel_control_12_3":64,"channel_control_13_3":64,"channel_control_89_3":0},{"channel_program_4":0,"channel_control_10_4":64,"channel_control_7_4":127,"channel_control_11_4":127,"channel_control_81_4":0,"channel_control_82_4":0,"channel_control_86_4":127,"channel_control_85_4":127,"channel_control_1_4":0,"channel_control_76_4":64,"channel_control_5_4":1,"channel_control_37_4":0,"channel_nrpn_1_4":0,"channel_nrpn_2_4":0,"channel_nrpn_3_4":8192,"channel_control_65_4":0,"channel_control_66_4":0,"channel_control_64_4":0,"channel_control_68_4":0,"channel_control_103_4":0,"channel_control_102_4":0,"channel_nrpn_0_4":0,"channel_control_83_4":0,"channel_control_12_4":64,"channel_control_13_4":64,"channel_control_89_4":0},{"channel_program_5":0,"channel_control_10_5":64,"channel_control_7_5":127,"channel_control_11_5":127,"channel_control_81_5":0,"channel_control_82_5":0,"channel_control_86_5":127,"channel_control_85_5":127,"channel_control_1_5":0,"channel_control_76_5":64,"channel_control_5_5":1,"channel_control_37_5":0,"channel_nrpn_1_5":0,"channel_nrpn_2_5":0,"channel_nrpn_3_5":8192,"channel_control_65_5":0,"channel_control_66_5":0,"channel_control_64_5":0,"channel_control_68_5":0,"channel_control_103_5":0,"channel_control_102_5":0,"channel_nrpn_0_5":0,"channel_control_83_5":0,"channel_control_12_5":64,"channel_control_13_5":64,"channel_control_89_5":0},{"channel_program_6":0,"channel_control_10_6":64,"channel_control_7_6":127,"channel_control_11_6":127,"channel_control_81_6":0,"channel_control_82_6":0,"channel_control_86_6":127,"channel_control_85_6":127,"channel_control_1_6":0,"channel_control_76_6":64,"channel_control_5_6":1,"channel_control_37_6":0,"channel_nrpn_1_6":0,"channel_nrpn_2_6":0,"channel_nrpn_3_6":8192,"channel_control_65_6":0,"channel_control_66_6":0,"channel_control_64_6":0,"channel_control_68_6":0,"channel_control_103_6":0,"channel_control_102_6":0,"channel_nrpn_0_6":0,"channel_control_83_6":0,"channel_control_12_6":64,"channel_control_13_6":64,"channel_control_89_6":0},{"channel_program_7":0,"channel_control_10_7":64,"channel_control_7_7":127,"channel_control_11_7":127,"channel_control_81_7":0,"channel_control_82_7":0,"channel_control_86_7":127,"channel_control_85_7":127,"channel_control_1_7":0,"channel_control_76_7":64,"channel_control_5_7":1,"channel_control_37_7":0,"channel_nrpn_1_7":0,"channel_nrpn_2_7":0,"channel_nrpn_3_7":8192,"channel_control_65_7":0,"channel_control_66_7":0,"channel_control_64_7":0,"channel_control_68_7":0,"channel_control_103_7":0,"channel_control_102_7":0,"channel_nrpn_0_7":0,"channel_control_83_7":0,"channel_control_12_7":64,"channel_control_13_7":64,"channel_control_89_7":0},{"channel_program_8":0,"channel_control_10_8":64,"channel_control_7_8":127,"channel_control_11_8":127,"channel_control_81_8":0,"channel_control_82_8":0,"channel_control_86_8":127,"channel_control_85_8":127,"channel_control_1_8":0,"channel_control_76_8":64,"channel_control_5_8":1,"channel_control_37_8":0,"channel_nrpn_1_8":0,"channel_nrpn_2_8":0,"channel_nrpn_3_8":8192,"channel_control_65_8":0,"channel_control_66_8":0,"channel_control_64_8":0,"channel_control_68_8":0,"channel_control_103_8":0,"channel_control_102_8":0,"channel_nrpn_0_8":0,"channel_control_83_8":0,"channel_control_12_8":64,"channel_control_13_8":64,"channel_control_89_8":0},{"channel_program_9":0,"channel_control_10_9":64,"channel_control_7_9":127,"channel_control_11_9":127,"channel_control_81_9":0,"channel_control_82_9":0,"channel_control_86_9":127,"channel_control_85_9":127,"channel_control_1_9":0,"channel_control_76_9":64,"channel_control_5_9":1,"channel_control_37_9":0,"channel_nrpn_1_9":0,"channel_nrpn_2_9":0,"channel_nrpn_3_9":8192,"channel_control_65_9":0,"channel_control_66_9":0,"channel_control_64_9":0,"channel_control_68_9":0,"channel_control_103_9":0,"channel_control_102_9":0,"channel_nrpn_0_9":0,"channel_control_83_9":0,"channel_control_12_9":64,"channel_control_13_9":64,"channel_control_89_9":0},{"channel_program_10":0,"channel_control_10_10":64,"channel_control_7_10":127,"channel_control_11_10":127,"channel_control_81_10":0,"channel_control_82_10":0,"channel_control_86_10":127,"channel_control_85_10":127,"channel_control_1_10":0,"channel_control_76_10":64,"channel_control_5_10":1,"channel_control_37_10":0,"channel_nrpn_1_10":0,"channel_nrpn_2_10":0,"channel_nrpn_3_10":8192,"channel_control_65_10":0,"channel_control_66_10":0,"channel_control_64_10":0,"channel_control_68_10":0,"channel_control_103_10":0,"channel_control_102_10":0,"channel_nrpn_0_10":0,"channel_control_83_10":0,"channel_control_12_10":64,"channel_control_13_10":64,"channel_control_89_10":0},{"channel_program_11":0,"channel_control_10_11":64,"channel_control_7_11":127,"channel_control_11_11":127,"channel_control_81_11":0,"channel_control_82_11":0,"channel_control_86_11":127,"channel_control_85_11":127,"channel_control_1_11":0,"channel_control_76_11":64,"channel_control_5_11":1,"channel_control_37_11":0,"channel_nrpn_1_11":0,"channel_nrpn_2_11":0,"channel_nrpn_3_11":8192,"channel_control_65_11":0,"channel_control_66_11":0,"channel_control_64_11":0,"channel_control_68_11":0,"channel_control_103_11":0,"channel_control_102_11":0,"channel_nrpn_0_11":0,"channel_control_83_11":0,"channel_control_12_11":64,"channel_control_13_11":64,"channel_control_89_11":0},{"channel_program_12":0,"channel_control_10_12":64,"channel_control_7_12":127,"channel_control_11_12":127,"channel_control_81_12":0,"channel_control_82_12":0,"channel_control_86_12":127,"channel_control_85_12":127,"channel_control_1_12":0,"channel_control_76_12":64,"channel_control_5_12":1,"channel_control_37_12":0,"channel_nrpn_1_12":0,"channel_nrpn_2_12":0,"channel_nrpn_3_12":8192,"channel_control_65_12":0,"channel_control_66_12":0,"channel_control_64_12":0,"channel_control_68_12":0,"channel_control_103_12":0,"channel_control_102_12":0,"channel_nrpn_0_12":0,"channel_control_83_12":0,"channel_control_12_12":64,"channel_control_13_12":64,"channel_control_89_12":0},{"channel_program_13":0,"channel_control_10_13":64,"channel_control_7_13":127,"channel_control_11_13":127,"channel_control_81_13":0,"channel_control_82_13":0,"channel_control_86_13":127,"channel_control_85_13":127,"channel_control_1_13":0,"channel_control_76_13":64,"channel_control_5_13":1,"channel_control_37_13":0,"channel_nrpn_1_13":0,"channel_nrpn_2_13":0,"channel_nrpn_3_13":8192,"channel_control_65_13":0,"channel_control_66_13":0,"channel_control_64_13":0,"channel_control_68_13":0,"channel_control_103_13":0,"channel_control_102_13":0,"channel_nrpn_0_13":0,"channel_control_83_13":0,"channel_control_12_13":64,"channel_control_13_13":64,"channel_control_89_13":0},{"channel_program_14":0,"channel_control_10_14":64,"channel_control_7_14":127,"channel_control_11_14":127,"channel_control_81_14":0,"channel_control_82_14":0,"channel_control_86_14":127,"channel_control_85_14":127,"channel_control_1_14":0,"channel_control_76_14":64,"channel_control_5_14":1,"channel_control_37_14":0,"channel_nrpn_1_14":0,"channel_nrpn_2_14":0,"channel_nrpn_3_14":8192,"channel_control_65_14":0,"channel_control_66_14":0,"channel_control_64_14":0,"channel_control_68_14":0,"channel_control_103_14":0,"channel_control_102_14":0,"channel_nrpn_0_14":0,"channel_control_83_14":0,"channel_control_12_14":64,"channel_control_13_14":64,"channel_control_89_14":0},{"channel_program_15":0,"channel_control_10_15":64,"channel_control_7_15":127,"channel_control_11_15":127,"channel_control_81_15":0,"channel_control_82_15":0,"channel_control_86_15":127,"channel_control_85_15":127,"channel_control_1_15":0,"channel_control_76_15":64,"channel_control_5_15":1,"channel_control_37_15":0,"channel_nrpn_1_15":0,"channel_nrpn_2_15":0,"channel_nrpn_3_15":8192,"channel_control_65_15":0,"channel_control_66_15":0,"channel_control_64_15":0,"channel_control_68_15":0,"channel_control_103_15":0,"channel_control_102_15":0,"channel_nrpn_0_15":0,"channel_control_83_15":0,"channel_control_12_15":64,"channel_control_13_15":64,"channel_control_89_15":0}],"custom_tunings":{"tunings":[{"semitone":15},{"semitone":5},{"semitone":3},{"semitone":3},{"semitone":4},{"semitone":11},{"semitone":8},{"semitone":8},{"semitone":16},{"semitone":11},{"semitone":11},{"semitone":11},{"semitone":12},{"semitone":13},{"semitone":14},{"semitone":14},{"semitone":16},{"semitone":17},{"semitone":18},{"semitone":19},{"semitone":20},{"semitone":21},{"semitone":22},{"semitone":23},{"semitone":24},{"semitone":25},{"semitone":26},{"semitone":27},{"semitone":28},{"semitone":29},{"semitone":30},{"semitone":31},{"semitone":32},{"semitone":33},{"semitone":34},{"semitone":35},{"semitone":36},{"semitone":37},{"semitone":38},{"semitone":39},{"semitone":40},{"semitone":81},{"semitone":42},{"semitone":98},{"semitone":44},{"semitone":45},{"semitone":46},{"semitone":47},{"semitone":48},{"semitone":49},{"semitone":50},{"semitone":51},{"semitone":52},{"semitone":53},{"semitone":54},{"semitone":55},{"semitone":56},{"semitone":57},{"semitone":58},{"semitone":59},{"semitone":60},{"semitone":81},{"semitone":62},{"semitone":63},{"semitone":64},{"semitone":65},{"semitone":66},{"semitone":67},{"semitone":68},{"semitone":69},{"semitone":70.4146},{"semitone":71.5561},{"semitone":84.7945},{"semitone":60},{"semitone":74},{"semitone":55},{"semitone":69},{"semitone":24},{"semitone":36},{"semitone":82},{"semitone":80},{"semitone":105},{"semitone":82},{"semitone":83},{"semitone":84},{"semitone":85},{"semitone":86},{"semitone":87},{"semitone":88},{"semitone":89},{"semitone":90},{"semitone":91},{"semitone":92},{"semitone":93},{"semitone":94},{"semitone":95},{"semitone":96},{"semitone":97},{"semitone":98},{"semitone":99},{"semitone":100},{"semitone":101},{"semitone":102},{"semitone":103},{"semitone":104},{"semitone":105},{"semitone":106},{"semitone":107},{"semitone":108},{"semitone":109},{"semitone":110},{"semitone":111},{"semitone":112},{"semitone":113},{"semitone":114},{"semitone":115},{"semitone":116},{"semitone":117},{"semitone":118},{"semitone":119},{"semitone":120},{"semitone":121},{"semitone":122},{"semitone":123},{"semitone":124},{"semitone":125},{"semitone":126},{"semitone":127}]}}
rianhunter commented 2 years ago

Hi Sean, I am the author of the Super MIDI Pak web app. This email was a request to create an export to my format but there is also the option for me to import one of your file exports. I think that might be a better experience for my users. Question for you, what do you think would be the best format to support for importing? I would implement SCL/KBM but it seems like it needs two files instead of one, is there a better standard single-file format for setting a specific frequency on each MIDI key?

frostburn commented 2 years ago

rianhunter commented 4 minutes ago

...there is also the option for me to import one of your file exports.

I think SCL/KBM and TUN are the most popular ones. TUN lists all individual pitches in cents for each MIDI key as measured from standard MIDI note 0.

Here are references to our TUN exporter and importer: https://github.com/xenharmonic-devs/scale-workshop/blob/457de46bee535661c9922ab0061b714b48bf41aa/src/exporters/anamark.ts https://github.com/xenharmonic-devs/scale-workshop/blob/457de46bee535661c9922ab0061b714b48bf41aa/src/importers/anamark.ts

We also have a bespoke export format planned #34, but not implemented yet.

rianhunter commented 2 years ago

@frostburn Thank you for the suggestion, TUN seems like it should be good. I'll try to get that working.

SeanArchibald commented 2 years ago

It's worth mentioning that the TUN format has different versions, V1, V1.5, V2. V2 contains all the same info as previous versions but adds programmatic ways of generating the tuning from the file, which makes implementation much more difficult. As a result, most synths don't support V2 but only the earlier V1.5. You might consider doing the same - ignore the V2 data and just read from the list of individual pitches.

rianhunter commented 1 year ago

While digging into this today I noticed that the tun v1 files that Scale Workshop exports are not supported on import. Was that intentional?

frostburn commented 1 year ago

rianhunter commented 11 minutes ago

While digging into this today I noticed that the tun v1 files that Scale Workshop exports are not supported on import. Was that intentional?

It's partly intentional so that we can display a nicely formatted finite scale which is only available in v2, but you are right to point this out. There's no reason why we shouldn't load a full 128 note scale in the app. I'll make a separate issue for this.

rianhunter commented 1 year ago

I've implemented basic TUN v1 importing into my application so there is little need to add an export option to my session file format. From my perspective you may close this issue.

frostburn commented 1 year ago

rianhunter commented 5 hours ago

I've implemented basic TUN v1 importing into my application so there is little need to add an export option to my session file format. From my perspective you may close this issue.

Thank You! I'm marking this as out of scope. Might be a fun exercise for a new developer one day, but not that important.

nsputnik commented 1 year ago

Hi Sean and Rian. Thank you both for supporting this. Sean, I tried exporting AnaMark v1 tuning (.tun) and I could not import it into SMP. However, I found the contents of a tun file in a form, copied that text into a text file and tried upload that, it works. That contained note numbers like: note 1=4827, their value in hertz. Scale Workshop's AnaMark v1 tuning (.tun) values looks like this: 1=-25800unixnote.

Also, what do you recommend to convert an scl+kbm into a tun?

nsputnik commented 1 year ago

OK, I found the issue. When I download a tuning from Scale Workshop on a Mac it places unix markes in it. On Windows it is fine. Sean, I think this is could be a matter of setting the right MIME type on the server.

frostburn commented 1 year ago

nsputnik commented 5 hours ago

OK, I found the issue. When I download a tuning from Scale Workshop on a Mac it places unix markes in it. On Windows it is fine.

Can you test if going to Preferences and setting Line endings format to Microsoft (Windows/MS-DOS) fixes the issue on a Mac?

nsputnik commented 1 year ago

nsputnik commented 5 hours ago

OK, I found the issue. When I download a tuning from Scale Workshop on a Mac it places unix markes in it. On Windows it is fine.

Can you test if going to Preferences and setting Line endings format to Microsoft (Windows/MS-DOS) fixes the issue on a Mac?

Now it seems to be output the files properly correctly regardless of the endings format.