Skip to content

Commit

Permalink
Arpeggios seem to be working
Browse files Browse the repository at this point in the history
  • Loading branch information
dpsanders committed Dec 28, 2023
1 parent acf3a22 commit 2c44f65
Show file tree
Hide file tree
Showing 4 changed files with 99 additions and 10 deletions.
4 changes: 4 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ authors = ["David Sanders <dpsanders@gmail.com> and contributors"]
version = "1.0.0-DEV"

[deps]
ColorTypes = "3da002f7-5984-5a60-b8a6-cbb66c0b333f"
Colors = "5ae59095-9a9b-59fe-a467-6f913c188581"
GeometryTypes = "4d00f742-c7ba-57c2-abde-4428a4b178cb"
Luxor = "ae8d54c2-7ccd-5906-9d76-62fc9837b5bc"
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"

[compat]
julia = "1"
Expand Down
9 changes: 2 additions & 7 deletions src/intervals.jl
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ struct Interval
quality::IntervalQuality
end

interval(distance, quality) = Interval(distance - 1, quality)
# interval(distance, quality) = Interval(distance - 1, quality)

function interval_name(distance::Int)
if distance == 0
Expand Down Expand Up @@ -43,7 +43,6 @@ interval_quality_semitones = Dict(
semitone(interval::Interval) =
interval_semitones[interval.distance] + interval_quality_semitones[interval.quality]

Base.:(<=)(n1::Pitch, n2::Pitch) = semitone(n1) <= semitone(n2)



Expand All @@ -64,10 +63,6 @@ function interval(n1::Pitch, n2::Pitch)
base_interval_semitone = interval_semitones[total_note_distance %7]
alteration_distance = semitone_distance - base_interval_semitone



@show note_distance, total_note_distance, semitone_distance, base_interval_semitone, alteration_distance

if abs(note_distance) + 1 (1, 4, 5)
if alteration_distance == 0
return Interval(total_note_distance, Perfect)
Expand All @@ -89,10 +84,10 @@ function interval(n1::Pitch, n2::Pitch)
end
end

interval( (n1, n2) ) = interval(n1, n2)

tone(interval::Interval) = interval.distance


function add_interval(n::Note, interval::Interval)
new_tone = (tone(n) + tone(interval)) % 7

Expand Down
4 changes: 3 additions & 1 deletion src/notes.jl
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,6 @@ Note(n::Note) = n

const middle_C = C4

semitone(middle_C)

Base.isless(n1::Pitch, n2::Pitch) = semitone(n1) < semitone(n2)

92 changes: 90 additions & 2 deletions src/scales.jl
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,96 @@ end
# iterate(s)

const M = MusicTheory
s = Scale(M.C4, major_scale)
# s = Scale(M.C4, major_scale)

# notes = Base.Iterators.take(s, 8) |> collect

iterate(s, C4)
# iterate(s, C4)

s = Scale(M.C♮4, melodic_minor_scale)

# makes thirds from scale tones:
notes = Base.Iterators.take(s, 10) |> collect

thirds = zip(notes, notes[3:end]) |> collect

thirds_intervals = interval.(thirds)
note_intervals = interval.(zip(notes, notes[2:end]))

all = []
for i in 1:(length(thirds)-1)
push!(all, (note_intervals[i], thirds_intervals[i], thirds_intervals[i+1]))
end

all

1 |> collect




# repeating pattern: how many scale notes to increment for each subsequent note

arpeggio = [2, 2, 3]
# broken thirds = [2, -1]
# broken octaves = [7, -6]
# broken arpeggio = [4, -2, 5]

# stateful iterator:
mutable struct Motif
scale::Scale
pattern::Vector{Int}
current::Pitch
i
end

Motif(scale, pattern) = Motif(scale, pattern, first(iterate(scale)), 1)

function Base.iterate(m::Motif)
return_value = m.current
current, next = iterate(scale)

for i in 1:m.pattern[m.i] - 1
current, next = iterate(scale, next)
end

m.i += 1
if m.i > length(m.pattern)
m.i = 1
end

m.current = current
return return_value, next
end

function Base.iterate(m::Motif, next)

return_value = next

for i in 1:m.pattern[m.i]
current, next = iterate(scale, next)
end

m.i += 1
if m.i > length(m.pattern)
m.i = 1
end

m.current = current

return return_value, next
end


Base.IteratorSize(::Type{Motif}) = Base.IsInfinite()
Base.IteratorEltype(::Type{Motif}) = Base.HasEltype()
Base.eltype(::Type{Motif}) = Pitch


scale = Scale(M.C4, major_scale)
arpeggio = Motif(scale, [2, 2, 3])

# arpeggio

current, next = iterate(arpeggio)
current, next = iterate(arpeggio, next)

0 comments on commit 2c44f65

Please sign in to comment.