diff --git a/CHANGELOG.md b/CHANGELOG.md index fb08e95..14eebc6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Project.toml b/Project.toml index 06726a9..66b9502 100644 --- a/Project.toml +++ b/Project.toml @@ -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" diff --git a/src/note.jl b/src/note.jl index 55feffd..632c082 100644 --- a/src/note.jl +++ b/src/note.jl @@ -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: @@ -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 @@ -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: @@ -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) diff --git a/test/note.jl b/test/note.jl index f5eb9cb..6aaf5a4 100644 --- a/test/note.jl +++ b/test/note.jl @@ -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