Tools for music analysis and generation
Project description
tonal
Tools for music analysis and generation
To install: pip install tonal
Examples
notes
The notes module provides tools for working with musical scales, notes, and MIDI data.
Key Concepts
Scale Quality: The characteristic sound or "flavor" of a scale, determined by its specific pattern of intervals (semitones) from the root note. Examples include major, minor, pentatonic, blues, or whole-tone.
Semitone Pattern: A numerical representation of a musical scale, showing the precise distance in semitones (half-steps) of each note from the starting (root) note. For example, the semitone pattern for a major scale is (0, 2, 4, 5, 7, 9, 11).
Working with Scales and MIDI Notes
The scale_midi_notes function converts scale specifications into MIDI note numbers:
from tonal.notes import scale_midi_notes
# Get all C major notes in the middle octave range
notes = scale_midi_notes('C major', midi_range=(60, 72))
print(notes) # (60, 62, 64, 65, 67, 69, 71, 72)
# Minor pentatonic scale
notes = scale_midi_notes('A minor pentatonic', midi_range=(57, 70))
print(notes) # (57, 60, 62, 64, 67, 69)
# If no root is specified, defaults to C
notes = scale_midi_notes('dorian', midi_range=(60, 72))
print(notes) # (60, 62, 63, 65, 67, 69, 70, 72)
Other Utilities
The module also provides:
semitone_pattern(quality): Get the semitone intervals for any scale qualityscale_params(scale_string): Parse scale strings into root note and quality components- Registration functions: Dynamically add new scales, chords, and aliases:
register_scale_quality(),register_chord_quality()register_root_note(),register_scale_quality_alias()
- Listing functions: Explore available musical elements:
list_scale_qualities(),list_chord_qualities()list_root_notes(),list_scale_quality_aliases()
from tonal.notes import semitone_pattern, scale_params, list_scale_qualities
# Get the interval pattern for blues scale
pattern = semitone_pattern('blues')
print(pattern) # (0, 3, 5, 6, 7, 10)
# Parse a scale string
root, quality = scale_params('F# harmonic minor')
print(f"Root: {root}, Quality: {quality}") # Root: F#, Quality: harmonic minor
# See all available scale qualities
qualities = list_scale_qualities()
print(f"Available scales: {len(qualities)} total")
chords
from tonal import chords_to_wav
chord_sequence = [
('Bdim', 120),
('Em11', 120),
('Amin9', 120),
('Dm7', 120),
'G7',
'Cmaj7',
]
wav_filepath = chords_to_wav(chord_sequence)
If you have hum you can use it to diplay (and hear) the sound:
from hum import Sound
Sound.from_file(wav_filepath).display()
Change the way the chords are played, and what the name (really, filepath) of the midi and wav files produce are.
from tonal.chords import play_arpeggio
Sound.from_file(
chords_to_wav(chord_sequence, name='test_arpeggio', render_chord=play_arpeggio)
).display()
counterpoint
The `translate_in_scale` allows you to translate a sequence of notes, or multiple
tracks of notes by the given number of steps within the given scale.
>>> stream = translate_in_scale(['C4', 'E4', 'B3', 'C4'], -2, 'C')
>>> stream # doctest: +ELLIPSIS
<music21.stream.Stream ...>
>>> note_names(stream)
['A3', 'C4', 'G3', 'A3']
For multiple tracks:
>>> tracks = [['C4', 'E4', 'G4'], ['A4', 'C5', 'E5']]
>>> translated_tracks = translate_in_scale(tracks, -2, 'C')
>>> multi_note_names(translated_tracks)
[['A3', 'C4', 'E4'], ['F4', 'A4', 'C5']]
Using some other scales:
With a E major scale:
>>> tracks = [['E4', 'G#4', 'B4'], ['C#5', 'E5', 'G#5']]
>>> translated_tracks = translate_in_scale(tracks, 1, 'E')
>>> multi_note_names(translated_tracks)
[['F#4', 'A4', 'C#5'], ['D#5', 'F#5', 'A5']]
With a D flat major scale:
>>> tracks = [['Db4', 'F4', 'Ab4'], ['Bb4', 'Db5', 'F5']]
>>> translated_tracks = translate_in_scale(tracks, -3, 'Db')
>>> multi_note_names(translated_tracks)
[['A-3', 'C4', 'E-4'], ['F4', 'A-4', 'C5']]
Now let's use a different, "custom" scale, as well as demonstrate the use
of a partial function to get a translator with a fixed input scale:
>>> from functools import partial
>>> from music21.scale import HarmonicMinorScale
>>> translate = partial(
... translate_in_scale, input_scale='A', scale_creator=HarmonicMinorScale
... )
>>> tracks = [['A4', 'C5', 'E5'], ['G#5', 'A5', 'C6']]
>>> translated_tracks = translate(tracks, 2)
>>> multi_note_names(translated_tracks)
[['C5', 'E5', 'G#5'], ['B5', 'C6', 'E6']]
Let's make a four part cycling V-I progression.
from tonal.counterpoint import translate_in_scale, create_score_from_tracks
from tonal.util import play_music21_object
motif = [
"C4 C4".split(),
"E4 E4".split(),
"G4 F4".split(),
"B4 A4".split(),
]
tracks = translate_in_scale(motif, range(7, -14, -1), 'C')
score = create_score_from_tracks(tracks)
score.show()
play_music21_object(score)
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file tonal-0.0.17.tar.gz.
File metadata
- Download URL: tonal-0.0.17.tar.gz
- Upload date:
- Size: 9.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b6b83a0c3146cc607b0d6f18104e953b2c45290cf34dbedd234302f9658aefdd
|
|
| MD5 |
fbe75a5f3aa8f8c033d69dc4c6ccf175
|
|
| BLAKE2b-256 |
44292fa60f73fac4ea5d8d1cf76b6244760a36b038387d5c87949604ac5efd4f
|
File details
Details for the file tonal-0.0.17-py3-none-any.whl.
File metadata
- Download URL: tonal-0.0.17-py3-none-any.whl
- Upload date:
- Size: 930.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.10.19
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3b2a4c3322d59a15afb3ec66ad4e070e4a003ae973d1d3d22a6f4b4bd06e82dd
|
|
| MD5 |
59b164cd987f8f774600313926872aed
|
|
| BLAKE2b-256 |
8eda5c0656ec95504b59601ff8f79a14b7b1048656ae876171f6ae1e35d3b378
|