Skip to content

Commit

Permalink
simplify Pitch class
Browse files Browse the repository at this point in the history
just use SpecificNote.i instead different i for Pitch
  • Loading branch information
tandav committed Jun 1, 2024
1 parent f25de4d commit 835d613
Show file tree
Hide file tree
Showing 4 changed files with 26 additions and 85 deletions.
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ ci:

repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.5.0
rev: v4.6.0
hooks:
- id: check-added-large-files
- id: check-yaml
Expand All @@ -27,7 +27,7 @@ repos:
- id: add-trailing-comma

- repo: https://github.com/asottile/pyupgrade
rev: v3.15.1
rev: v3.15.2
hooks:
- id: pyupgrade

Expand All @@ -37,12 +37,12 @@ repos:
# - id: autopep8

- repo: https://github.com/PyCQA/autoflake
rev: v2.3.0
rev: v2.3.1
hooks:
- id: autoflake

- repo: https://github.com/charliermarsh/ruff-pre-commit
rev: v0.2.2
rev: v0.4.7
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
Expand All @@ -61,7 +61,7 @@ repos:
# https://github.com/christopherpickering/pylint-per-file-ignores/issues/76

- repo: https://github.com/pre-commit/mirrors-mypy
rev: v1.8.0
rev: v1.10.0
hooks:
- id: mypy
additional_dependencies:
Expand Down
6 changes: 3 additions & 3 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ disallow_untyped_defs = false

# ==============================================================================

[tool.ruff]
[tool.ruff.lint]
select = ["ALL"]
ignore = [
"E501", # line too long
Expand Down Expand Up @@ -128,7 +128,7 @@ ignore = [
"PTH123",
]

[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"tests/*" = [
"S101",
"PLR2004",
Expand All @@ -139,7 +139,7 @@ ignore = [
"N806",
]

[tool.ruff.isort]
[tool.ruff.lint.isort]
force-single-line = true

# ==============================================================================
Expand Down
26 changes: 6 additions & 20 deletions src/musiclib/pitch.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,38 +10,24 @@ def __init__(
self,
hz_tuning: float = 440,
origin_note: SpecificNote = A4,
transpose: float = 0,
) -> None:
"""
origin_note: in midi format, A4 midi (A3 in ableton) ~ 440Hz
origin_note: in midi format, A4 midi ~ 440Hz ~ midi number i=69
"""
self.hz_tuning = hz_tuning
self.origin_note = origin_note
self.transpose = transpose

def i_to_hz(self, i: float) -> float:
return self.hz_tuning * 2 ** ((i + self.transpose) / 12)
return self.hz_tuning * 2 ** ((i - self.origin_note.i) / 12)

def hz_to_i(self, hz: float) -> float:
return 12 * math.log2(hz / self.hz_tuning) - self.transpose

def note_i_to_hz(self, note_i: float) -> float:
return self.i_to_hz(note_i - self.origin_note.i)

def hz_to_note_i(self, hz: float) -> float:
return self.origin_note.i + self.hz_to_i(hz)
return 12 * math.log2(hz / self.hz_tuning) + self.origin_note.i

def note_to_hz(self, note: SpecificNote) -> float:
return self.note_i_to_hz(note.i)
return self.i_to_hz(note.i)

def hz_to_note(self, hz: float) -> SpecificNote:
return SpecificNote.from_i(round(self.hz_to_note_i(hz)))

def note_to_i(self, note: SpecificNote) -> float:
return note.i - self.origin_note.i

def i_to_note(self, i: float) -> SpecificNote:
return SpecificNote.from_i(round(self.origin_note.i + i))
return SpecificNote.from_i(round(self.hz_to_i(hz)))

@staticmethod
def hz_to_px(hz: float, hz_min: float, hz_max: float, px_max: float) -> float:
Expand All @@ -55,4 +41,4 @@ def px_to_hz(px: float, hz_min: float, hz_max: float, px_max: float) -> float:
return hz_min ** (1 - c) * hz_max ** c # type: ignore[no-any-return]

def __repr__(self) -> str:
return f'Pitch(hz_tuning={self.hz_tuning!r}, origin_note={self.origin_note!r}, transpose={self.transpose!r})'
return f'Pitch(hz_tuning={self.hz_tuning!r}, origin_note={self.origin_note!r})'
69 changes: 12 additions & 57 deletions tests/pitch_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,8 @@
('x', 's', 'r'), [
(
Pitch(),
"Pitch(hz_tuning=440, origin_note=SpecificNote('A', 4), transpose=0)",
"Pitch(hz_tuning=440, origin_note=SpecificNote('A', 4), transpose=0)",
"Pitch(hz_tuning=440, origin_note=SpecificNote('A', 4))",
"Pitch(hz_tuning=440, origin_note=SpecificNote('A', 4))",
),
],
)
Expand All @@ -34,34 +34,18 @@ def test_str_repr(x, s, r):

@pytest.mark.parametrize(
('i', 'hz'), [
(-24, 110),
(-12, HZ_220),
(-9, HZ_261),
(0, HZ_440),
(1, HZ_466),
(2, HZ_493),
(12, HZ_880),
],
)
def test_i_hz(i, hz):
pitch = Pitch()
assert pitch.i_to_hz(i) == hz
assert int(pitch.hz_to_i(hz)) == i


@pytest.mark.parametrize(
('note_i', 'hz'), [
(A3.i, HZ_220),
(C4.i, HZ_261),
(A4.i, HZ_440),
(b4.i, HZ_466),
(C4.i, HZ_261),
(A4.i + 0.5, HZ_452),
(B4.i, HZ_493),
(A5.i, HZ_880),
],
)
def test_note_i_hz(note_i, hz):
def test_i_hz(i, hz):
pitch = Pitch()
assert pitch.note_i_to_hz(note_i) == hz
assert pitch.hz_to_note_i(hz) == note_i
assert pitch.i_to_hz(i) == hz
assert int(pitch.hz_to_i(hz)) == i


@pytest.mark.parametrize(
Expand All @@ -78,10 +62,10 @@ def test_round(hz, note):

@pytest.mark.parametrize(
('hz_tuning', 'origin_note', 'i', 'hz'), [
(HZ_220, A5, 0, HZ_220),
(HZ_220, A5, 12, HZ_440),
(HZ_440, A4, 0, HZ_440),
(HZ_440, A4, -12, HZ_220),
(HZ_220, A5, A5.i, HZ_220),
(HZ_220, A5, A6.i, HZ_440),
(HZ_440, A4, A4.i, HZ_440),
(HZ_440, A4, A3.i, HZ_220),
],
)
def test_tuning_origin_note(hz_tuning, origin_note, i, hz):
Expand Down Expand Up @@ -117,32 +101,3 @@ def test_note_hz(note, hz):
def test_hz_to_px(hz, px, hz_min, hz_max, px_max):
assert Pitch.hz_to_px(hz, hz_min, hz_max, px_max) == pytest.approx(px)
assert Pitch.px_to_hz(px, hz_min, hz_max, px_max) == pytest.approx(hz)


@pytest.mark.parametrize(
('note', 'transpose', 'hz'), [
(A4, -12, HZ_220),
(A4, +12, HZ_880),
(A4, +1, HZ_466),
(A4, +0.5, HZ_452),
],
)
def test_transpose(note, transpose, hz):
pitch = Pitch(transpose=transpose)
assert pitch.note_to_hz(note) == hz
assert pitch.hz_to_note(hz) == note


@pytest.mark.parametrize(
('note', 'i'), [
(A4, 0),
(A5, 12),
(A3, -12),
(b4, 1),
(C4, -9),
],
)
def test_note_to_i(note, i):
pitch = Pitch()
assert pitch.note_to_i(note) == i
assert pitch.i_to_note(i) == note

0 comments on commit 835d613

Please sign in to comment.