|
|
|
01-16-2018, 01:35 AM
|
#1
|
Human being with feelings
Join Date: May 2016
Posts: 720
|
MIDI note naming conversion
I'm thinking of adding this user convenience to something I'm working on - it's most clearly demonstrated by example, I think.
Function can take "character+number" string input, eg "C4" and return the corresponding MIDI number, in this case 60. Which I believe is REAPER's default (without preference offset).
It seems likely to me that is already possible or has already been scripted, so before I reinvent the wheel, can anyone point me to it please.
|
|
|
01-16-2018, 07:31 AM
|
#2
|
Human being with feelings
Join Date: Jul 2017
Location: Hackensack
Posts: 347
|
You must have something in mind, otherwise, you can just see the note name & midi number in the piano roll view. At the top left there are 2 small boxes - one shows the measure/beat of a selected note and the second shows the note name/MIDI number.
|
|
|
01-16-2018, 08:13 AM
|
#3
|
Human being with feelings
Join Date: May 2016
Posts: 720
|
Quote:
Originally Posted by Michael AD
You must have something in mind, otherwise, you can just see the note name & midi number in the piano roll view. At the top left there are 2 small boxes - one shows the measure/beat of a selected note and the second shows the note name/MIDI number.
|
I'm talking about giving a user the option to type a note name into an input box and translate it into the numeric format needed to manipulate it in a script.
What I have in mind, in pseudo-code:
Get user string
Check input is valid - first char "A-G"/"a-g", second char optional "#", third char "0-9"
Translate to MIDI number
I could program the last instruction from scratch, but I was just wondering whether it's already a part of the REAPER API or has been programmed.
|
|
|
01-16-2018, 08:56 AM
|
#4
|
Human being with feelings
Join Date: Oct 2008
Location: Right Hear
Posts: 15,618
|
Jason might be thinking about how to add that to his split script...?
don't know the real answer but I think it might be there in reaper cuz you can get a drop down in the MIDI Ed Filter to pick a note by name
|
|
|
01-16-2018, 09:30 AM
|
#5
|
Human being with feelings
Join Date: May 2016
Posts: 720
|
Quote:
Originally Posted by hopi
Jason might be thinking about how to add that to his split script...?
don't know the real answer but I think it might be there in reaper cuz you can get a drop down in the MIDI Ed Filter to pick a note by name
|
That is the initial use, yup. I'm also tinkering with ideas for automating (or semi-automating) the creation of MIDI note name maps for eg instrument registers. Theoretically, I think you could run a script to scan through a VSTi, autogenerate the note names for all the notes that do something (including ccs) and then set the MIDI editor to display only active. But that's one challenge at a time.
I can think of other immediate uses for it though - eg input two note names in a dialog and do just about anything you like to every note between.
I think it would make a useful auxiliary function anyway - surely most people find it more natural to think D3 A3 and F#4 than 38 45 and 66?
I'll give it a few more days and if answer comes there none, I suppose I might as well get on with string parsing as tightly as I can.
(If I'm honest, it's actually a little bit of an excuse to avoid work. With a big orchestral job on the stove, you can get a bit jaded and need some light relief... So jaded in fact, that investigating a new API and scripting language counts as light relief...)
PS Check out also the selected item to new track splitter that I've cooked up with DarrenH. Might be useful, you never know.
|
|
|
01-16-2018, 09:25 PM
|
#6
|
Human being with feelings
Join Date: May 2016
Posts: 720
|
The tightest and as error-trapped I've so far come up with. Doesn't handle negative octaves and I haven't put it in function form yet.
If anyone's interested, please feel free to try and break it, or suggest streamlining.
Code:
-- declare vars
local notcancelled, input
-- get user input
notcancelled, input = reaper.GetUserInputs("Convert MIDI Note Name", 1, "Enter Name", "C4")
if notcancelled then -- input error trap: continue if input not cancelled
------- code to parse input
-- declare vars
local inputlen = string.len(input), notename, octave
if inputlen == 2 and string.find(input, "%a%d") then -- input is of form eg "W2"
notename = string.sub(input, 1, 1)
octave = tonumber(string.sub(input, 2, 2)) end
if inputlen == 3 and string.find(input, "%a[#]%d") then -- input is of form eg "j#8"
notename = string.sub(input, 1, 2)
octave = tonumber(string.sub(input, 3, 3)) end
if notename then -- function error trap 1: continue if input is confirmed as above
-- declare vars
local octavetable, i, noteval
notename = string.upper(notename)
octavetable = {"C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"}
for i = 1, 12 do
if notename == octavetable[i] then noteval = i - 1 end
end
if noteval then -- function error trap 2: continue if note name matches a table value
MIDINUMRESULT = (octave+1)*12 + noteval
NNAME = notename
OCTAVE = octave
end end --- close function error traps
-------
end -- close input error trap
Last edited by Jason Lyon; 01-16-2018 at 11:40 PM.
|
|
|
01-17-2018, 09:35 AM
|
#7
|
Human being with feelings
Join Date: Sep 2009
Posts: 863
|
As a function, and a slightly different kludgy approach
Code:
function getMIDINote(str)
local notes = {c=12, d=14, e=16, f=17, g=19, a=21, b=23}
local str = str:lower()
local t = {}
for c in str:gmatch"." do table.insert(t, c) end
local num = 0
for k, v in pairs(t) do
if k == 1 and not notes[v] then num = -1 break end -- first char should be a letter
if notes[v] then num = num + notes[v]-- if in the note table, get the note number
elseif v == "#" then num = num + 1 -- if it's sharp, add 1
elseif v == "-" then -- negative octave
return (num -12) -- only down to =1
elseif string.gmatch(v, "%d") then -- there's an octave to handle
if tonumber(v) >= 2 and tonumber(v) <= 10 then num = math.floor(num + ((v-1) * 12)) end
else -- invalid input
num = -1
break
end
end
return tonumber(num)
end
user_input = "c#4"
print(getMIDINote(user_input))
Handle negative octaves down to -1 (c=0), and positive up to 9
Return -1 if the input is invalid
Results are consistent with this chart
It doesn't handle flats "b" but should be easy to add
Not tested it in Reaper, only in Notepad++'s Lua plugin, but should be fine.
Bug-ette: Handling of sharps does not check for valid note values - it will accept things like 'e#' but it will return the correct note number, e.g. f in this case.
Last edited by RobU; 01-18-2018 at 12:07 AM.
|
|
|
01-17-2018, 03:15 PM
|
#8
|
Human being with feelings
Join Date: May 2016
Posts: 720
|
Thanks Rob.
I'll have a look when I get a chance and run a speed comparison.
|
|
|
01-18-2018, 10:13 AM
|
#9
|
Human being with feelings
Join Date: Oct 2008
Location: Right Hear
Posts: 15,618
|
hey... good ideas.... even if all you got to was a way to generate midi note name files very quickly, that in itself would be a boon!
I'll certainly keep watching the progress
|
|
|
Thread Tools |
|
Display Modes |
Linear Mode
|
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -7. The time now is 04:33 AM.
|