Lua Musical Notes to Numbers - lua

I need to convert some musical note inputs representing a chord to numbers above it's root note 0 using Lua.
So from the midi data we get the notes of a C13 Chord
input: C, E, G, A#, D, F, A
as the root note 0 is C we start on the C note,
below we have 2 octaves of a piano keyboard, 12 notes on each where chords are played
0C 1C# 2D 3D# 4E 5F 6F# 7G 8G# 9A 10A# 11B 12C 13C# 14D 15D# 16E 17F 18F# 19G 20G# 21A 22A# 23B
so C is the root note 0
D,F,A are played on the next octave
result: 0,4,7,10,14,17,21
so if we have a D chord
input: D,F#,A
D is the root note 0
all notes played on the first octave
0D 1D# 2E 3F 4F# 5G 6G# 7A 8A# 9B 10C 11C# 12D 13D# 14E 15F 16F# 17G 18G# 19A 20A# 21B 22C 23C#
result: 0,4,7
G#m7#9 Chord
input: G#,B,D#,F#,B
0G# 1A 2A# 3B 4C 5C# 6D 7D# 8E 9F 10F# 11G 12G# 13A 14A# 15B 16C 17C# 18D 19D# 20E 21F 22F# 23G
result: 0,3,7,10,15

Something like this may work:
local function notes2nums(input)
local map = {A = 9, ["A#"] = 10, B = 11, C = 0, ["C#"] = 1, D = 2, ["D#"] = 3, E = 4, F = 5, ["F#"] = 6, G = 7, ["G#"] = 8}
local base, prev
return (input:gsub("([^,]+)", function(note)
local num = map[note] or error(("Unexpected note value '%s'"):format(note))
base = base or num
num = num - base
if prev and num < prev then num = num + 12 end
prev = num
return tostring(num)
end))
end
print(notes2nums("D,F#,A"))
print(notes2nums("C,E,G,A#,D,F,A"))
print(notes2nums("G#,B,D#,F#,B"))
This prints:
0,4,7
0,4,7,10,14,17,21
0,3,7,10,15

Related

Creating a crc8 function with lua

Is there a simple algorithm to create a crc8 checksum from a table in lua?
Polynomial should be x^8+x^5+x^4+1 (0x31)
This algorithm will be used to check the UID of the DS28CM00 UID-chip.
Here you can find a table returned by the chip (LS-byte last) :
table = {112,232,9,80,1,0,0}
Thanks for any help
For Lua 5.3+
local function crc8(t)
local c = 0
for _, b in ipairs(t) do
for i = 0, 7 do
c = c >> 1 ~ ((c ~ b >> i) & 1) * 0x8C
end
end
return c
end
print(crc8{112, 232, 9, 80, 1, 0, 0}) --> 219
print(crc8{2, 0x1C, 0xB8, 1, 0, 0, 0}) --> 0xA2 as in example from AN-27
For Lua 5.2-
local function crc8(t)
local c = 0
for _, b in ipairs(t) do
for i = 0, 7 do
local c0 = c % 2
local b0 = b % 2
c = (c - c0) / 2
b = (b - b0) / 2
if c0 + b0 == 1 then
c = c + 0x80 + (c % 16 < 8 and 8 or -8) + (c % 8 < 4 and 4 or -4)
end
end
end
return c
end

Adaptation of SHA2 512 gives incorrect results

I am trying to adapt the pure Lua implementation of the SecureHashAlgorithm found here for SHA2 512 instead of SHA2 256. When I try to use the adaptation, it does not give the correct answer.
Here is the adaptation:
--
-- UTILITY FUNCTIONS
--
-- transform a string of bytes in a string of hexadecimal digits
local function str2hexa (s)
local h = string.gsub(s, ".", function(c)
return string.format("%02x", string.byte(c))
end)
return h
end
-- transforms number 'l' into a big-endian sequence of 'n' bytes
--(coded as a string)
local function num2string(l, n)
local s = ""
for i = 1, n do
--most significant byte of l
local remainder = l % 256
s = string.char(remainder) .. s
--remove from l the bits we have already transformed
l = (l-remainder) / 256
end
return s
end
-- transform the big-endian sequence of eight bytes starting at
-- index 'i' in 's' into a number
local function s264num (s, i)
local n = 0
for i = i, i + 7 do
n = n*256 + string.byte(s, i)
end
return n
end
--
-- MAIN SECTION
--
-- FIRST STEP: INITIALIZE HASH VALUES
--(second 32 bits of the fractional parts of the square roots of the first 9th through 16th primes 23..53)
local HH = {}
local function initH512(H)
H = {0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1, 0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179}
return H
end
-- SECOND STEP: INITIALIZE ROUND CONSTANTS
--(first 80 bits of the fractional parts of the cube roots of the first 80 primes 2..409)
local k = {
0x428a2f98d728ae22, 0x7137449123ef65cd, 0xb5c0fbcfec4d3b2f, 0xe9b5dba58189dbbc, 0x3956c25bf348b538,
0x59f111f1b605d019, 0x923f82a4af194f9b, 0xab1c5ed5da6d8118, 0xd807aa98a3030242, 0x12835b0145706fbe,
0x243185be4ee4b28c, 0x550c7dc3d5ffb4e2, 0x72be5d74f27b896f, 0x80deb1fe3b1696b1, 0x9bdc06a725c71235,
0xc19bf174cf692694, 0xe49b69c19ef14ad2, 0xefbe4786384f25e3, 0x0fc19dc68b8cd5b5, 0x240ca1cc77ac9c65,
0x2de92c6f592b0275, 0x4a7484aa6ea6e483, 0x5cb0a9dcbd41fbd4, 0x76f988da831153b5, 0x983e5152ee66dfab,
0xa831c66d2db43210, 0xb00327c898fb213f, 0xbf597fc7beef0ee4, 0xc6e00bf33da88fc2, 0xd5a79147930aa725,
0x06ca6351e003826f, 0x142929670a0e6e70, 0x27b70a8546d22ffc, 0x2e1b21385c26c926, 0x4d2c6dfc5ac42aed,
0x53380d139d95b3df, 0x650a73548baf63de, 0x766a0abb3c77b2a8, 0x81c2c92e47edaee6, 0x92722c851482353b,
0xa2bfe8a14cf10364, 0xa81a664bbc423001, 0xc24b8b70d0f89791, 0xc76c51a30654be30, 0xd192e819d6ef5218,
0xd69906245565a910, 0xf40e35855771202a, 0x106aa07032bbd1b8, 0x19a4c116b8d2d0c8, 0x1e376c085141ab53,
0x2748774cdf8eeb99, 0x34b0bcb5e19b48a8, 0x391c0cb3c5c95a63, 0x4ed8aa4ae3418acb, 0x5b9cca4f7763e373,
0x682e6ff3d6b2b8a3, 0x748f82ee5defb2fc, 0x78a5636f43172f60, 0x84c87814a1f0ab72, 0x8cc702081a6439ec,
0x90befffa23631e28, 0xa4506cebde82bde9, 0xbef9a3f7b2c67915, 0xc67178f2e372532b, 0xca273eceea26619c,
0xd186b8c721c0c207, 0xeada7dd6cde0eb1e, 0xf57d4f7fee6ed178, 0x06f067aa72176fba, 0x0a637dc5a2c898a6,
0x113f9804bef90dae, 0x1b710b35131c471b, 0x28db77f523047d84, 0x32caab7b40c72493, 0x3c9ebe0a15c9bebc,
0x431d67c49c100d4c, 0x4cc5d4becb3e42b6, 0x597f299cfc657e2a, 0x5fcb6fab3ad6faec, 0x6c44198c4a475817
}
-- THIRD STEP: PRE-PROCESSING (padding)
local function preprocess(toProcess, len)
--append a single '1' bit
--append K '0' bits, where K is the minimum number >= 0 such that L + 1 + K = 896mod1024
local extra = 128 - (len + 9) % 128
len = num2string(8 * len, 8)
toProcess = toProcess .. "\128" .. string.rep("\0", extra) .. len
assert(#toProcess % 128 == 0)
return toProcess
end
local function rrotate(rot, n)
return (rot >> n) | ((rot << 64 - n))
end
local function digestblock(msg, i, H)
local w = {}
for j = 1, 16 do w[j] = s264num(msg, i + (j - 1)*4) end
for j = 17, 80 do
local v = w[j - 15]
local s0 = rrotate(v, 1) ~ rrotate(v, 8) ~ (v >> 7)
v = w[j - 2]
w[j] = w[j - 16] + s0 + w[j - 7] + ((rrotate(v, 19) ~ rrotate(v, 61)) ~ (v >> 6))
end
local a, b, c, d, e, f, g, h = H[1], H[2], H[3], H[4], H[5], H[6], H[7], H[8]
for i = 1, 80 do
a, b, c, d, e, f, g, h = a , b , c , d , e , f , g , h
local s0 = rrotate(a, 28) ~ (rrotate(a, 34) ~ rrotate(a, 39))
local maj = ((a & b) ~ (a & c)) ~ (b & c)
local t2 = s0 + maj
local s1 = rrotate(e, 14) ~ (rrotate(e, 18) ~ rrotate(e, 41))
local ch = (e & f) ~ (~e & g)
local t1 = h + s1 + ch + k[i] + w[i]
h, g, f, e, d, c, b, a = g, f, e, d + t1, c, b, a, t1 + t2
end
H[1] = (H[1] + a)
H[2] = (H[2] + b)
H[3] = (H[3] + c)
H[4] = (H[4] + d)
H[5] = (H[5] + e)
H[6] = (H[6] + f)
H[7] = (H[7] + g)
H[8] = (H[8] + h)
end
local function finalresult512 (H)
-- Produce the final hash value:
return
str2hexa(num2string(H[1], 8)..num2string(H[2], 8)..num2string(H[3], 8)..num2string(H[4], 8)..
num2string(H[5], 8)..num2string(H[6], 8)..num2string(H[7], 8)..num2string(H[8], 8))
end
-- Returns the hash512 for the given string.
local function hash512 (msg)
msg = preprocess(msg, #msg)
local H = initH512(HH)
-- Process the message in successive 1024-bit (128 bytes) chunks:
for i = 1, #msg, 128 do
digestblock(msg, i, H)
end
return finalresult512(H)
end
Given hash512("a"):
Expect: 1f40fc92da241694750979ee6cf582f2d5d7d28e18335de05abc54d0560e0f5302860c652bf08d560252aa5e74210546f369fbbbce8c12cfc7957b2652fe9a75
Actual: e0b9623f2194cb81f2a62616a183edbe390be0d0b20430cadc3371efc237fa6bf7f8b48311f2fa249131c347fee3e8cde6acfdab286d648054541f92102cfc9c
I know that I am creating a message of the correct bit size (1024 bits) and also working in 1024-bit chunks, or at least I believe I am.
I am not sure if it has to do with the handling of the integers (the standard requires unsigned integers) or whether I made a mistake in one of the utility functions, or both. If it is indeed an issue with the handling of the integers, how would I go about taking care of the problem. I was able to resolve this when working on the 256-bit version of the adaptation by using mod 2^32 when working with numbers in the digestblock method. I attempted to do mod 2^64 and 2^63 with the 512-bit version and it does not correct the problem. I am stumped.
I should mention that I cannot use one of the many library implementations as I am using a sandboxed Lua that does not provide this access, which is why I need a pure lua implementation. Thanks in advance.
Unfortunately, after introducing integers in Lua 5.3 writing scripts for Lua becomes a more complicated task.
You must always think about transformations between integers and floating point numbers.
ALWAYS. Yes, that's boring.
One of your mistakes is an excellent example of this "dark corner of Lua".
local remainder = l % 256
s = string.char(remainder) .. s
--remove from l the bits we have already transformed
l = (l-remainder) / 256
Your value l is initially a 64-bit integer.
After cutting off its first byte l contains (64-8) = 56 bits, but now it's a floating point-number (with 53-bit precision, of course).
Possible solution: use l = l >> 8 or l = l // 256 instead of l = (l-remainder) / 256
Another mistake is using s264num(msg, i + (j - 1) * 4) instead of s264num(msg, i + (j - 1) * 8)
One more mistake is in the following line:
local extra = 128 - (len + 9) % 128
The correct code is
local extra = - (len + 17) % 128 + 8
(Please note that -a%m+b is not the same as b-a%m due to operator precedence)
After fixing these 3 mistakes your code works correctly.

Function closures with mapslices

In the code snipped below, functions f and g are returning different values. From reading the code, you would expect them to behave the same. I am guessing it is to do with closure of v -> innerprodfn(m, v). How do I do it to get the desired behaviour where f and g return the same values.
type Mat{T<:Number}
data::Matrix{T}
end
innerprodfn{T}(m::Mat{T}, v::Array{T}) = i -> (m.data*v)[i]
innerprodfn{T}(m::Mat{T}, vv::Matrix{T}) = mapslices(v->innerprodfn(m, v), vv, 1)
m = Mat(collect(reshape(0:5, 2, 3)))
v = collect(reshape(0:11, 3, 4))
f = innerprodfn(m, v[:,1])
g = innerprodfn(m, v)[1]
m.data * v
# 10 28 46 64
# 13 40 67 94
[f(1) g(1); f(2) g(2)]
# 10 64
# 13 94
I don't have an explanation for the observed behavior, but on a recent nightly version of Julia one gets the expected result.
On 0.5, a workaround is to use a comprehension:
innerprodfn{T}(m::Mat{T}, vv::Matrix{T}) = [innerprodfn(m, vv[:,i]) for i in indices(vv, 2)]
Of course, this works on 0.6 as well.

Pairs in lua programming

I have two set of values defined:
local A1 = {100, 200, 300, 400}
local A2 = {500, 600, 700, 800}
I want to iterate a loop assigning values for another variable B1 and B2 as pairs from A1 and A2 as follows:
B1 = 100 and B2 = 500 (first iteration)
B1 =200 and B2 = 600 (second iteration)
B1 = 300 and B2 = 700 (third iteration)
B1=400 and B2 = 800 (fourth iteration)
I tried to use ipairs as follows:
for i, f1 in ipairs(A1) do
for j, f2 in ipairs(A2) do
B1 = f1
B2 = f2
end
end
but this gave me
B1 = 100 and B2 = 500 (first iteration)
B1 =100 and B2 = 600 (second iteration)
B1 = 100 and B2 = 700 (third iteration)
B1=100 and B2 = 800 (fourth iteration)
B1 = 200 and B2 = 500 (fifth iteration)
B1 =200 and B2 = 600 (sixth iteration)
B1 =200 and B2 = 700 (seventh iteration)
....
...
...
so on...
can anyone help me to code in the right way?
You can easily do this with a numerical loop:
for i = 1, 4 do
local a, b = A1[i], B1[i]
--- use them
end
How you go about determining the number of iterations you'll need is the tricky part. If the sizes are variant, but each table is the same length as the others you can instead use the length operator (#A1).
Alternatively, you might want a function that returns the largest length of a given set of tables.
local function max_table_len (...)
local tabs = { ... }
local len = 0
for i = 1, #tabs do
local l = #tabs[i]
if l > len then
len = l
end
end
return len
end
And maybe even a helper function to get each value.
local function get_from_tables (index, ...)
local values = { ... }
local len = #values
for i = 1, len do
values[i] = values[i][index]
end
return table.unpack(values, 1, len)
end
Ending up with something like:
for index = 1, max_table_len(A1, B1) do
local a, b = get_from_tables(index, A1, B1)
end
You can build on the ipairs example from Programming in Lua. For instance this version iterates over 2 sequences in parallel:
-- iterator function
local function iter_ipairs2(tablePair, i)
i = i + 1
local v1 = tablePair[1][i]
local v2 = tablePair[2][i]
-- if you use 'and' here the iteration stops after finishing
-- the shortest sequence. If you use 'or' the iteration
-- will stop after it finishes the longest sequence.
if v1 and v2 then
return i, v1, v2
end
end
-- this is the function you'll call from your other code:
local function ipairs2(t1, t2)
return iter_ipairs2, {t1, t2}, 0
end
-- usage:
local A1 = {100, 200, 300, 400, 500}
local A2 = {500, 600, 700, 800}
for i, v1, v2 in ipairs2(A1, A2) do
print(i, v1, v2)
end
The previous answers are more detailed and provide a more general and better answer.
This one is for someone very new to Lua. Not only does it show two loops, it reinforces that there is usually more than one way to get where you want to go.
local A1 = {100, 200, 300, 400}
local A2 = {500, 600, 700, 800}
print("simplest answer:")
-- doesn't use ipairs and assumes A1 and A2 are the same size
for i = 1, #A1 do
B1 = A1[i]
B2 = A2[i]
print(B1, B2, "(iteration #"..i..")")
end
print()
print("answer that uses ipairs:")
-- again, assumes A1 and A2 are the same size
for i, v in ipairs(A1) do
B1 = A1[i] -- i steps through A1 and A2
B2 = A2[i] -- this works because A1 and A2 are same size
print(B1, B2, "(iteration #"..i..")")
end
Gives this output:
simplest answer:
100 500 (iteration #1)
200 600 (iteration #2)
300 700 (iteration #3)
400 800 (iteration #4)
answer that uses ipairs:
100 500 (iteration #1)
200 600 (iteration #2)
300 700 (iteration #3)
400 800 (iteration #4)

Select Diagonal Elements of a Matrix in MATLAB

Consider the following matrix in MATLAB:
01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49
I have to generate directional variograms for such 7 x 7 windows(moving) of an image. I will use nlfilter for the process but for developing the function to calculate variograms I am not able to decide how to select elements in the window. For example when I consider the central value 25, in EW direction I have to consider only 25, 26, 27 and 28; in NE direction I have to consider only 25, 19, 13 and 07 when the lag chosen is 1. Is there any standard command to do so?
You can also do it like this:
A = eye(5);
v = A(1:size(A,1)+1:end);
resulting in
v = [1 1 1 1 1]
You can write a function to get these elements yourself easily:
A = [01 02 03 04 05 06 07
08 09 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31 32 33 34 35
36 37 38 39 40 41 42
43 44 45 46 47 48 49];
c = (size(A)+1)/2;
EW = A(c(1),c(2):end)
NE = diag(A(c(1):-1:1,c(2):end))
Just write this code in a function (preferably an m-file), perform your operation and pass the result back.
The diag function returns the diagonal elements of a matrix (or returns a diagonal matrix when passed a vector).
This is Generic matrix solution (not for MATLAB)
suppose matrix AxB =
[01 AA 03 04 05 06 07
08 09 AA 11 12 13 AA
AA 16 17 AA 19 AA 21
22 AA 24 25 AA 27 28
AA 30 AA 32 33 34 35
36 AA 38 AA 40 41 42
43 44 AA 46 AA 48 49];
in this matrix we want to search continuously 3 times appearence of AA diagonally.
Solution:-
step 1
for whole matrix we have to create 4 seperate for loops to search the appearence of AA continuously 3 times
i am adding method through which a user can search all loop and can find the item.
local function check_win( matrx_table)
local counter = 1
local term = "AA"
local D = 1
-- for horizontal check for win---
for i = 1, no_rows, 1 do
for j= 1, no_Columns, 1 do
if((j+1) <= no_Columns) then
if(table_mXn[i][j] == term and table_mXn[i][j+1] == term)then
counter = counter + 1;
else
counter = 1
end
if(counter == 3)then
return counter
end
end
end
end
counter = 1
-- for vertical check for win--
for i = 1, no_Columns, 1 do
for j= no_rows, 1, -1 do
if((j-1) >= 1) then
if(table_mXn[j][i] == term and table_mXn[j-1][i] == term)then
counter = counter + 1;
else
counter = 1
end
if(counter == 3)then
return counter
end
end
end
end
counter = 1
D = 1
-- for diagonol left half check for win in figure loop 1--
for m = 1, no_rows, 1 do
D = 1
for i =m, no_rows,1 do
if(i+1 <= no_rows and D+1 <= no_Columns)then
if(table_mXn[i][D] == term and table_mXn[i+1][D+1] == term)then
counter = counter + 1;
print("hhhhh")
else
counter = 1
end
if(counter == 3)then
return counter
end
D = D + 1
end
end
end
counter = 1
D = 1
-- for diagonol right half check for win in figure loop 2--
for m = 1, no_rows, 1 do
D = m
for i =1, no_rows,1 do
if(i+1 <= no_rows and D+1 <= no_Columns)then
if(table_mXn[i][D] == term and table_mXn[i+1][D+1] == term)then
counter = counter + 1;
print("hhhhh")
else
counter = 1
end
if(counter == 3)then
return counter
end
D = D + 1
end
end
end
counter = 1
D = 1
-- for diagonol left half check for win in figure loop 3--
for m = 1, no_rows, 1 do
D = no_Columns
for i =m, no_rows,1 do
if(i+1 <= no_rows and D-1 >= 1)then
if(table_mXn[i][D] == term and table_mXn[i+1][D-1] == term)then
counter = counter + 1;
print("hhhhh")
else
counter = 1
end
if(counter == 3)then
return counter
end
D = D - 1
end
end
end
counter = 1
D = 1
-- for diagonol left half check for win in figure loop 4--
for m = no_Columns, 1, -1 do
D = m
for i =1, no_rows,1 do
if(i+1 <= no_rows and D-1 >= 1)then
if(table_mXn[i][D] == term and table_mXn[i+1][D-1] == term)then
counter = counter + 1;
print("hhhhh")
else
counter = 1
end
if(counter == 3)then
return counter
end
D = D - 1
end
end
end
end
now you can call this method any where in class and can check in that matrix the searchable item is available or not in repeatedly order Horizontally, Vertically and diagonally.

Resources