From 835d613836d7081728792de872c3631783bb9b4e Mon Sep 17 00:00:00 2001 From: Alexander Rodionov Date: Sat, 1 Jun 2024 11:15:53 +0300 Subject: [PATCH] simplify Pitch class just use SpecificNote.i instead different i for Pitch --- .pre-commit-config.yaml | 10 +++--- pyproject.toml | 6 ++-- src/musiclib/pitch.py | 26 ++++------------ tests/pitch_test.py | 69 +++++++---------------------------------- 4 files changed, 26 insertions(+), 85 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index affb820c..2f970bcb 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -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 @@ -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 @@ -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] @@ -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: diff --git a/pyproject.toml b/pyproject.toml index 85439050..65fcc1c1 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -100,7 +100,7 @@ disallow_untyped_defs = false # ============================================================================== -[tool.ruff] +[tool.ruff.lint] select = ["ALL"] ignore = [ "E501", # line too long @@ -128,7 +128,7 @@ ignore = [ "PTH123", ] -[tool.ruff.per-file-ignores] +[tool.ruff.lint.per-file-ignores] "tests/*" = [ "S101", "PLR2004", @@ -139,7 +139,7 @@ ignore = [ "N806", ] -[tool.ruff.isort] +[tool.ruff.lint.isort] force-single-line = true # ============================================================================== diff --git a/src/musiclib/pitch.py b/src/musiclib/pitch.py index 98e20b52..9bb6f260 100644 --- a/src/musiclib/pitch.py +++ b/src/musiclib/pitch.py @@ -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: @@ -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})' diff --git a/tests/pitch_test.py b/tests/pitch_test.py index 5332e84d..0856c305 100644 --- a/tests/pitch_test.py +++ b/tests/pitch_test.py @@ -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))", ), ], ) @@ -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( @@ -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): @@ -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