Skip to content

Commit 8033a30

Browse files
committed
add repeat function
1 parent bf98275 commit 8033a30

File tree

3 files changed

+40
-7
lines changed

3 files changed

+40
-7
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33
All notable changes to this project will be documented in this file.
44

55
This project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
6+
# 1.4.0
7+
* New function `repeat`.
8+
* `combine` now works with `Vector{Vector{<:Note}}` as well.
9+
610
# 1.3.0
711
* `translate, transpose, louden` now also work on single notes.
812

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "MusicManipulations"
22
uuid = "274955c0-c284-5bf7-b122-5ecd51c559de"
33
repo = "https://github.com/JuliaMusic/MusicManipulations.jl.git"
4-
version = "1.3.0"
4+
version = "1.4.0"
55

66
[deps]
77
MIDI = "f57c4921-e30c-5f49-b073-3f2f2ada663e"

src/general.jl

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ N(n.pitch, n.velocity+ticks, n.position, n.duration, n.channel)
7575

7676
"""
7777
timesort!(notes::Notes)
78-
Sort the `notes` by their temporal position.
79-
Non-mutating version also exists.
78+
In-place sort the `notes` by their temporal position.
79+
Use `timesort` for a non-mutating version.
8080
"""
8181
function timesort!(notes::Notes)
8282
sort!(notes.notes, by = x -> x.position)
@@ -90,20 +90,31 @@ Combine the given container (either `Array{Notes}` or `Dict{Any, Notes}`) into
9090
a single `Notes` instance. In the process, sort the notes by position in the
9191
final container.
9292
"""
93-
function combine(notearray::AbstractArray{<:Notes})
93+
function combine(notearray::AbstractArray{<:Notes}, tsort = true)
9494
notes = copy(notearray[1])
9595
for i in 2:length(notearray)
9696
append!(notes, notearray[i])
9797
end
98-
timesort!(notes)
98+
tsort && timesort!(notes)
99+
return notes
99100
end
100101

101-
function combine(notedict::Dict{<:Any, Notes{N}}) where {N}
102+
function combine(notearray::AbstractArray{<:AbstractArray{<:AbstractNote}}, tsort=true)
103+
notes = copy(notearray[1])
104+
for i in 2:length(notearray)
105+
append!(notes, notearray[i])
106+
end
107+
tsort && timesort!(notes)
108+
return notes
109+
end
110+
111+
function combine(notedict::Dict{<:Any, Notes{N}}, tsort = true) where {N}
102112
n = Notes(N[], first(values(notedict)).tpq)
103113
for (k, v) in notedict
104114
append!(n, v)
105115
end
106-
timesort!(n)
116+
tsort && timesort!(n)
117+
return n
107118
end
108119

109120

@@ -126,3 +137,21 @@ function relpos(notes::Notes, grid)
126137
end
127138
return rpos
128139
end
140+
141+
"""
142+
repeat(notes, i = 1)
143+
Repeat the `notes` `i` times, by successively adding duplicates of `notes`
144+
shifted by the total duration of `notes`. Return a single `Notes` container
145+
for convenience.
146+
147+
The function assumes that notes are `timesort`ed.
148+
"""
149+
Base.repeat(n::Notes, i::Int = 1) = Notes(repeat(n.notes, i), n.tpq)
150+
function Base.repeat(n::Vector{<:AbstractNote}, i::Int = 1)
151+
maxdur = maximum(a.position + a.duration for a in n)
152+
r = [copy(n)]
153+
for j in 1:i
154+
push!(r, translate(r[end], maxdur))
155+
end
156+
return combine(r, false)
157+
end

0 commit comments

Comments
 (0)