Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Set version to 0.1 and update README #11

Merged
merged 1 commit into from
Jan 1, 2024
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
7 changes: 1 addition & 6 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,14 +1,9 @@
name = "MusicTheory"
uuid = "564e61e1-4667-41b2-a4a2-754a0240c775"
authors = ["David Sanders <[email protected]> and contributors"]
version = "1.0.0-DEV"
version = "0.1"

[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
53 changes: 44 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,22 +2,22 @@

[![Build Status](https://github.com/dpsanders/MusicTheory.jl/actions/workflows/CI.yml/badge.svg?branch=main)](https://github.com/dpsanders/MusicTheory.jl/actions/workflows/CI.yml?query=branch%3Amain)

A Julia package for the basics of ("Western") music theory.
(Currently) everything is based on semitones.
The goal of this package is to provide a Julian interface for representing
the objects and structures in ("Western") music theory (based on semitones).

## Contents
- Pitches with scientific notation, e.g. C4 for middle C
- Intervals
- Scales
- Chords
- Notes and rests with durations
- Chords

## Pitches
Pitch names are exported in the `MusicTheory.PitchNames` submodule.

Specifying just the name of a pitch gives a `PitchClass`, representing all notes of that
pitch, e.g.
```
```jl
julia> C♯
C♯

Expand All @@ -26,28 +26,28 @@ PitchClass
```

Indexing gives a pitch with a specific octave, e.g.
```
```jl
julia> C♯[4]
C♯₄
```

## Intervals
The `Interval` type computes the interval between two pitches:
```
```jl
julia> Interval(C[4], E[4])
Major 3rd
```

## Scales
General scales are supported; they are specified as a sequence of intervals dividing up an
octave, e.g.
```
```jl
julia> show(major_scale)
Interval[Major 2nd, Major 2nd, Minor 2nd, Major 2nd, Major 2nd, Major 2nd, Minor 2nd]
```

The `Scale` type is a standard Julia iterator over the scale:
```
```jl
julia> scale = Scale(C[4], major_scale)
Scale{Pitch}(C₄, Dict{PitchClass, Interval}(C => Major 2nd, E => Minor 2nd, B => Minor 2nd, F => Major 2nd, D => Major 2nd, G => Major 2nd, A => Major 2nd))

Expand All @@ -60,14 +60,49 @@ Pitch[C₄, D₄, E₄, F₄, G₄, A₄, B₄, C₅]
## Notes
Notes have a pitch and a duration, which is a rational number, e.g. `1 // 4` for a
quarter note (crotchet). Rests are specified using `rest`, e.g.
```
```jl
julia> notes = [C[5] / 4, rest / 8, D[5] / 8]
3-element Vector{Note}:
Note(C₅, 1//4)
Note(MusicTheory.Rest(), 1//8)
Note(D₅, 1//8)
```

## Example
A motivating example for writing this package was to be able to do the following types of
computations.

When playing the violin, it's common to have a scale in thirds: take a scale and for each
scale tone, play the note two steps above it in the scale at the same time.

Question: Which combinations of half/whole steps and pairs of major/minor thirds
are possible?

Answer:
```jl
julia> scale = Scale(C[4], major_scale)

julia> notes = Base.Iterators.take(scale, 10) |> collect

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

julia> thirds_intervals = Interval.(thirds)

julia> note_intervals = Interval.(zip(notes, notes[2:end]))

julia> combinations =
[ (note_intervals[i], thirds_intervals[i], thirds_intervals[i+1])
for i in 1:(length(thirds)-1)
]

julia> result = unique(combinations)
4-element Vector{Tuple{Interval, Interval, Interval}}:
(Major 2nd, Major 3rd, Minor 3rd)
(Major 2nd, Minor 3rd, Minor 3rd)
(Minor 2nd, Minor 3rd, Major 3rd)
(Major 2nd, Major 3rd, Major 3rd)
```

## Author

Copyright David P. Sanders, 2024