From 20c1c1ac0a7a698786370a668af54fa024d60e98 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Wed, 30 Apr 2014 17:28:15 +0200 Subject: [PATCH 1/3] Created note API Functionality: * `note.midi(n: number or string)`: Converts a note in string form (e.g. A#4 or Gb3, will be documented on the wiki) or a given frequency into the respective MIDI code * `note.freq(n: number or string)`: Converts a note in string form (e.g. A#4) or a given MIDI code into the respective frequency * `note.get(n: number)`: Converts a MIDI value back into a string; if you have a frequency to convert, just use note.get(note.midi(frequency)) * `note.ticks(n: number)`: Converts note block ticks (0-24) into MIDI code (34-58, respectively) and vice-versa. Useful for use with note blocks and OpenComponents * `note.play(tone: string or number,duration: number)`: Plays a note from a string or MIDI code via computer.beep --- .../assets/opencomputers/lua/rom/lib/note.lua | 120 ++++++++++++++++++ 1 file changed, 120 insertions(+) create mode 100644 src/main/resources/assets/opencomputers/lua/rom/lib/note.lua diff --git a/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua b/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua new file mode 100644 index 000000000..3bdbe5ea2 --- /dev/null +++ b/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua @@ -0,0 +1,120 @@ +--Provides all music notes in range of computer.beep in MIDI and frequency form +--Author: Vexatos +local computer = require("computer") + +local note = {} +local notes = {} +local reverseNotes = {} + +do + local tempNotes = { + "c", + "c#", + "d", + "d#", + "e", + "f", + "f#", + "g", + "g#", + "a", + "a#", + "b" + } + local sNotes = {} + local bNotes = {} + + --Registers all possible notes in order + do + table.insert(sNotes,"a0") + table.insert(sNotes,"a#0") + table.insert(bNotes,"bb0") + table.insert(sNotes,"b0") + for i = 1,6 do + for _,v in ipairs(tempNotes) do + table.insert(sNotes,v..tostring(i)) + if #v == 1 and v ~= "c" and v ~= "f" then + table.insert(bNotes,v.."b"..tostring(i)) + end + end + end + end + for i=21,95 do + notes[sNotes[i-20]]=tostring(i) + end + + do + for k,v in pairs(notes) do + reverseNotes[tonumber(v)]=k + end + end + + --This is registered after reverseNotes to avoid conflicts + for k,v in ipairs(bNotes) do + notes[v]=tostring(notes[string.gsub(v,"(.)b(.)","%1%2")]-1) + end +end + +--Converts string or frequency into MIDI code +function note.midi(n) + if type(n) == "string" then + n = string.lower(n) + if tonumber(notes[n])~=nil then + return tonumber(notes[n]) + else + error("Error: Wrong input "..tostring(n).." given to note.midi, needs to be [semitone sign], e.g. A#0 or Gb4") + end + elseif type(n) == "number" then + return math.floor((12*math.log(n/440,2))+69) + else + error("Error: Wrong input "..tostring(n).." given to note.midi, needs to be a number or a string") + end +end + +--Converts String or MIDI code into frequency +function note.freq(n) + if type(n) == "string" then + n = string.lower(n) + if tonumber(notes[n])~=nil then + return math.pow(2,(tonumber(notes[n])-69)/12)*440 + else + error("Error: Wrong input "..tostring(n).." given to note.freq, needs to be [semitone sign], e.g. A#0 or Gb4",2) + end + elseif type(n) == "number" then + return math.pow(2,(n-69)/12)*440 + else + error("Error: Wrong input "..tostring(n).." given to note.freq, needs to be a number or a string",2) + end +end + +--Converts a MIDI value back into a string +function note.get(n) + n = tonumber(n) + if reverseNotes[n] then + return string.upper(string.match(reverseNotes[n],"^(.)"))..string.gsub(reverseNotes[n],"^.(.*)","%1") + else + error("Error: Attempt to get a note for a non-exsisting MIDI code",2) + end +end + +--Converts Note block ticks (0-24) to MIDI code (34-58) and vice-versa +function note.ticks(n) + if type(n) == "number" then + if n>=0 and n<=24 then + return n+34 + elseif n>=34 and n<=58 then + return n-34 + else + error("Error: Wrong input "..tostring(n).." given to note.ticks, needs to be a number [0-24 or 34-58]",2) + end + else + error("Error: Wrong input "..tostring(n).." given to note.ticks, needs to be a number",2) + end +end + +--Plays a tone, input is either the note as a string or the MIDI code as well as the duration of the tone +function note.play(tone,duration) + computer.beep(note.freq(tone),duration) +end + +return note From 9de638e8840822d9f1ca6c51b6141c9fe9568537 Mon Sep 17 00:00:00 2001 From: Vexatos Date: Wed, 30 Apr 2014 17:50:26 +0200 Subject: [PATCH 2/3] Some tweaks --- .../assets/opencomputers/lua/rom/lib/note.lua | 22 ++++++++++++------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua b/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua index 3bdbe5ea2..90fe0cb42 100644 --- a/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua +++ b/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua @@ -3,10 +3,13 @@ local computer = require("computer") local note = {} +--The table containing all the notes local notes = {} +--The reversed table "notes" local reverseNotes = {} do + --All the base notes local tempNotes = { "c", "c#", @@ -21,7 +24,9 @@ do "a#", "b" } + --The table containing all the standard notes and # semitones in correct order, temporarily local sNotes = {} + --The table containing all the b semitones local bNotes = {} --Registers all possible notes in order @@ -43,6 +48,7 @@ do notes[sNotes[i-20]]=tostring(i) end + --Reversing the whole table in reverseNotes, used for note.get do for k,v in pairs(notes) do reverseNotes[tonumber(v)]=k @@ -62,12 +68,12 @@ function note.midi(n) if tonumber(notes[n])~=nil then return tonumber(notes[n]) else - error("Error: Wrong input "..tostring(n).." given to note.midi, needs to be [semitone sign], e.g. A#0 or Gb4") + error("Wrong input "..tostring(n).." given to note.midi, needs to be [semitone sign], e.g. A#0 or Gb4") end elseif type(n) == "number" then return math.floor((12*math.log(n/440,2))+69) else - error("Error: Wrong input "..tostring(n).." given to note.midi, needs to be a number or a string") + error("Wrong input "..tostring(n).." given to note.midi, needs to be a number or a string") end end @@ -78,22 +84,22 @@ function note.freq(n) if tonumber(notes[n])~=nil then return math.pow(2,(tonumber(notes[n])-69)/12)*440 else - error("Error: Wrong input "..tostring(n).." given to note.freq, needs to be [semitone sign], e.g. A#0 or Gb4",2) + error("Wrong input "..tostring(n).." given to note.freq, needs to be [semitone sign], e.g. A#0 or Gb4",2) end elseif type(n) == "number" then return math.pow(2,(n-69)/12)*440 else - error("Error: Wrong input "..tostring(n).." given to note.freq, needs to be a number or a string",2) + error("Wrong input "..tostring(n).." given to note.freq, needs to be a number or a string",2) end end --Converts a MIDI value back into a string -function note.get(n) +function note.name(n) n = tonumber(n) if reverseNotes[n] then return string.upper(string.match(reverseNotes[n],"^(.)"))..string.gsub(reverseNotes[n],"^.(.*)","%1") else - error("Error: Attempt to get a note for a non-exsisting MIDI code",2) + error("Attempt to get a note for a non-exsisting MIDI code",2) end end @@ -105,10 +111,10 @@ function note.ticks(n) elseif n>=34 and n<=58 then return n-34 else - error("Error: Wrong input "..tostring(n).." given to note.ticks, needs to be a number [0-24 or 34-58]",2) + error("Wrong input "..tostring(n).." given to note.ticks, needs to be a number [0-24 or 34-58]",2) end else - error("Error: Wrong input "..tostring(n).." given to note.ticks, needs to be a number",2) + error("Wrong input "..tostring(n).." given to note.ticks, needs to be a number",2) end end From 9dc2d2833b88bdd1413bf286523ab01e5fad6ceb Mon Sep 17 00:00:00 2001 From: Vexatos Date: Wed, 30 Apr 2014 17:57:08 +0200 Subject: [PATCH 3/3] Update note.lua --- src/main/resources/assets/opencomputers/lua/rom/lib/note.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua b/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua index 90fe0cb42..67b7c8704 100644 --- a/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua +++ b/src/main/resources/assets/opencomputers/lua/rom/lib/note.lua @@ -3,7 +3,7 @@ local computer = require("computer") local note = {} ---The table containing all the notes +--The table that maps note names to their respective MIDI codes local notes = {} --The reversed table "notes" local reverseNotes = {}