Skip to content

Commit

Permalink
Add note and notes constructor (#163)
Browse files Browse the repository at this point in the history
* add note constructor.

* use string to initialize Notes
  • Loading branch information
NeroBlackstone authored Jan 29, 2023
1 parent 74b4e78 commit e7d7ac1
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 1 deletion.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
# v2.5.0
* Implement `Note(pitch_name::String; position = 0, velocity = 100, duration = 960, channel = 0)`
* Implement `Notes(notes_string::String, tpq::Int = 960)`
# v2.4.0
* Implement `Base.empty!(::Notes)` and `Base.isempty(::Notes)`.
# v2.3.0
Expand Down
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name = "MIDI"
uuid = "f57c4921-e30c-5f49-b073-3f2f2ada663e"
repo = "https://github.com/JuliaMusic/MIDI.jl.git"
version = "2.4.0"
version = "2.5.0"

[deps]
FileIO = "5789e2e9-d7fb-5bc7-8068-2c6fae9b9549"
Expand Down
11 changes: 11 additions & 0 deletions src/note.jl
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ If the `channel` of the note is `0` (default), it is not shown.
You can also create a `Note` with the following keyword constructor:
```julia
Note(pitch, position; velocity = 100, duration = 960, channel = 0)
Note(pitch_name::String; position = 0, velocity = 100, duration = 960, channel = 0)
```
## Fields:
Expand Down Expand Up @@ -41,6 +42,8 @@ mutable struct Note <: AbstractNote
end
Note(pitch, position; velocity = 100, duration = 960, channel = 0) =
Note(pitch, velocity, position, duration, channel)
Note(pitch_name::String; position = 0, velocity = 100, duration = 960, channel = 0) =
Note(name_to_pitch(pitch_name), velocity, position, duration, channel)

@inline Note(n::Note) = n

Expand Down Expand Up @@ -69,9 +72,16 @@ N(n.pitch, n.velocity, n.position, n.duration, n.channel)

"""
Notes(note_vector, tpq = 960) -> Notes
Notes(notes_string::String, tpq::Int = 960) -> Notes
A data structure describing a collection of music notes, bundled with the ticks
per quarter note (so that the notes can be attributed rhythmic value).
Notes can be initialized by string, the name of notes are separated by spaces.
```julia
Notes("C2 F3 D#6")
```
`Notes` can be iterated and accessed as the given `note_vector`.
This eliminates the need for custom iteration or search functions.
For example, to get the note of maximum pitch you can do:
Expand All @@ -94,6 +104,7 @@ function Notes(notes::Vector{N}, tpq::Int = 960) where {N <: AbstractNote}
end

Notes(; tpq = 960) = Notes{Note}(Vector{Note}[], tpq)
Notes(notes_string::String, tpq::Int = 960) = Notes([Note(String(s)) for s in split(notes_string," ")], tpq)

# Iterator Interface for notes:
Base.iterate(n::Notes, i = 1) = iterate(n.notes, i)
Expand Down
10 changes: 10 additions & 0 deletions test/note.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,16 @@ cd(@__DIR__)
@test typeof(notes[1:3]) == Notes{Note}
@test typeof(notes[1:3]) <: Notes
@test notes[1:3].notes == notes.notes[1:3]

notes2 = Notes("C2 F3 D#6")
@test notes2[1].pitch == name_to_pitch("C2")
@test notes2[2].pitch == name_to_pitch("F3")
@test notes2[3].pitch == name_to_pitch("D#6")
end

@testset "Note" begin
c4 = Note("C4")
@test c4.pitch == name_to_pitch("C4")
end

@testset "pitch names" begin
Expand Down

0 comments on commit e7d7ac1

Please sign in to comment.