Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions array.lua
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,12 @@ function Array:equals(array)
return getmetatable(array) == Array
and #self == #array
and equal_values
end

function Array:sum()
local total = 0
for _, value in ipairs(self) do
total = total + value
end
return total
end
16 changes: 11 additions & 5 deletions scale.lua
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ function Scale.c_major()
})
end

function Scale:count_alterations()
return self.notes:map(function(n) return n.alteration end):sum()
end

--[[
Warning: only works for ionian scales
]]
Expand Down Expand Up @@ -110,12 +114,14 @@ end
Warning: only works for ionian scales
]]
function Scale:circle_of_5ths_rotate(iterations)
if(iterations == 0) then
local total_alterations = self:count_alterations()+iterations
local rotation = ( (total_alterations + 5) % 12 ) - 5
if(rotation == 0) then
return self
elseif(iterations < 0) then
return self:to_the_left_on_circle_of_5ths(-iterations)
elseif(iterations > 0) then
return self:to_the_right_on_circle_of_5ths(iterations)
elseif(rotation < 0) then
return self:to_the_left_on_circle_of_5ths(-rotation)
elseif(rotation > 0) then
return self:to_the_right_on_circle_of_5ths(rotation)
else
return "Error"
end
Expand Down
11 changes: 10 additions & 1 deletion test/test_scale.lua
Original file line number Diff line number Diff line change
Expand Up @@ -359,4 +359,13 @@ function TestScale:testGetDistance()
luaunit.assertEquals(f_sharp_maj:get_distance(g_flat_min), 2)
luaunit.assertEquals(f_sharp_maj:get_distance(d_sharp_min), 0)
luaunit.assertEquals(f_sharp_maj:get_distance(d_sharp_min_harm), 1)
end
end

function TestScale:test_c5ths_rotate()
local c_major = Scale.c_major()
luaunit.assertEquals(c_major:circle_of_5ths_rotate(12), c_major:circle_of_5ths_rotate(0))
luaunit.assertEquals(c_major:circle_of_5ths_rotate(8), c_major:circle_of_5ths_rotate(-4))
luaunit.assertEquals(c_major:circle_of_5ths_rotate(-8), c_major:circle_of_5ths_rotate(4))
luaunit.assertEquals(c_major:circle_of_5ths_rotate(123), c_major:circle_of_5ths_rotate(3))
luaunit.assertEquals(c_major:circle_of_5ths_rotate(-123), c_major:circle_of_5ths_rotate(-3))
end
Loading