Welcome to babs’s documentation!¶
Contents:
Installation¶
Download babs
git clone https://github.com/iskyd/babs
cd babs
Create virtual environment (OPTIONALS)
python -m venv venv
If you are using python you can use virtualenv
Install babs
pip install -e .
Coverage¶
pip install pytest-cov
pytest --cov=babs --cov-report html:htmlcov
It will create htmlcov directory with html report.
If everything goes well… You are ready to get started!
Note¶
-
class
Note
(freq, name, octave=4, alt='sharp', duration=4/4)¶ Return a musical Note representation from frequency or name
-
pitch_shift
(val[, half_step=False, octave=False, alt=None])¶ change the frequency of the current note
-
get_note_index
()¶ return the note index in Note.NOTES or False if not found
-
classmethod
get_note_name_by_index
(idx[, alt=None])¶ return the name of the note at specified idx in Note.NOTES. idx could be any number so that you don’t have to worry about idx > len(Note.NOTES)
-
Create your first note¶
from babs import Note
n = Note(freq=440)
Now you have create a Note with 440Hz of frequency (the A at 4th octave). So you now have access to attribute’s note.
print(n.freq) # 440
print(n.name) # 'A'
print(n.octave) # 4
print(n.duration) # 1.0 (4/4)
You can also create a note starting from it name.
n = Note(name='A')
print(n.freq) # 440
print(n.name) # 'A'
print(n.octave) # 4
print(n.duration) # 1.0 (4/4)
The freq params have the priority so if you specify the frequency, name and octave will be ignored:
n = Note(freq=440, name='B', octave=3)
print(n.freq) # 440
print(n.name) # 'A'
print(n.octave) # 4
Octave¶
The octave is note’s position on a standard 88-key piano keyboard and by default (as you can see in the previous example) is 4.
n = Note(name='A', octave=5)
print(n.freq) # 880.0
print(n.name) # 'A'
print(n.octave) # 5
print(n.duration) # 1.0 (4/4)
Alteration¶
Now let’s create a Bb note.
n = Note(freq=466.16)
print(n.name) # 'A#'
So we got A# as name because the A# and the Bb note has the same frequency. But what if you need to get a Bb? You can use alteration attribute.
n = Note(freq=466.16, alt='flat')
print(n.name) # 'Bb'
Duration¶
The duration represent the relative duration of the note.
n = Note(name='A', duration=3/4)
print(n.duration) # 0.75 -> 3/4
You can change the duration of the note simply using the setter.
print(n.duration) # 0.75 -> 3/4
n.duration = 2/4
print(n.duration) # 0.5 -> 3/4
Change attribute¶
You can easily change the note frequency and the note alteration. Babs will calculate again the name and the octave of the note.
n = Note(freq=440)
print(n.name) # 'A'
n.freq = 466.16
print(n.name) # 'A#'
n.alt = 'flat'
print(n.name) # 'Bb'
n.freq = 880
print(n.name) # 'A'
print(n.octave) # 5
Pitch shift¶
If you need more control to alter a note then just using the freq setter you can use a more powerful function, the pitch shift. The pitch shift can be used in three different way.
- Add or sub a frequency value
n = Note(freq=440)
n.pitch_shift(value=26.16) # Increase the freq by 26.16hz
print(n.freq) # 466.16
print(n.name) # 'A#'
n.pitch_shift(value=-26.16) # Decrease the freq by 26.16hz
print(n.freq) # 440.0
print(n.name) # 'A'
- Add or sub an octave value
n = Note(freq=440)
n.pitch_shift(value=2, octave=True) # Add 2 octaves
print(n.freq) # 1760.0
print(n.name) # 'A'
print(n.octave) # 6
n.pitch_shift(value=-3, octave=True) # Sub 3 octaves
print(n.freq) # 220.0
print(n.name) # 'A'
print(n.octave) # 3
- Add or sub an half tone value
n = Note(freq=440)
n.pitch_shift(value=2, half_step=True) # Add 1 tone (2 half tones)
print(n.freq) # 493.88
print(n.name) # 'B'
print(n.octave) # 4
n.pitch_shift(value=-12, half_step=True) # Sub 6 tones (6 tones = 1 octave)
print(n.freq) # 246.94
print(n.name) # 'B'
print(n.octave) # 3
With half_step and octave you can specify the alteration you need as before
n = Note(freq=440)
n.pitch_shift(value=1, half_step=True, alt='flat') # Add half tone
print(n.freq) # 466.16
print(n.name) # 'Bb'
print(n.octave) # 4
Remember that 0 is a valid value so the following will works:
n = Note(freq=466.16)
n.pitch_shift(value=0, alt='flat') # Add half tone
print(n.freq) # 466.16
print(n.name) # 'Bb'
print(n.octave) # 4
Consider that we can obtain the same result in this recommended way without using the pitch shift function:
n = Note(freq=466.16)
n.alt = 'flat' # Add half tone
print(n.freq) # 466.16
print(n.name) # 'Bb'
print(n.octave) # 4
__str__ and __repr__¶
__str__ will return the current name and octave of the note.
str(Note(freq=440)) # 'A4'
__repr__ will return the current representation of the Note so that you can call eval() on it.
repr(Note(freq=440)) # 'Note(freq=440, alt='None', duration=1.0)'
n = Note(freq=440, duration=1/8) # repr(n) -> Note(freq=440, alt='None', duration=0.125)
x = eval(repr(x)) # x will be the same as n
Comparison¶
Note support equal and not equal comparison operator. Two notes are the same if they have the same frequency and the same duration.
Note(name='A') == Note(name='A') # True
Note(name='A') == Note(name='A', duration=1/8) # False
Note(name='A') != Note(name='C') # True
Note(name='A') != Note(name='A', duration=1/8) # True
Rest¶
-
class
Rest
(duration=4/4)¶ Return a rest, an interval of silence. duration represent the relative duration of the rest.
__repr__¶
__repr__ will return the current representation of the Rest so that you can call eval() on it.
repr(Rest(duration=1/4)) # 'Rest(duration=0.25)'
r = Rest(duration=1/4)
x = eval(repr(r)) # x will be the same as r
Comparison¶
Rest support all comparison operator. This is just a shortcut of using .duration attribute.
Rest(duration=1/8) < Rest(duration=1/4) == Rest(duration=1/8).duration < Rest(duration=1/4).duration # True
NoteList¶
Create your first NoteList¶
NoteList is an abstract class, so you can’t instantiate it. We create a Mock class that extends NoteList in order to instantiate it.
from babs import Note, NoteList
class Mock(NoteList):
pass
m = Mock(Note(name='C'), Note(name='D'), Note(name='E'))
Now you have create the C chord and you can access to the notes attribute.
print(len(m.notes)
for n in m.notes:
print(n)
# 3
# C4
# D4
# E4
strict¶
As we said a NoteList consists of one or more note. So if we create an empty NoteList we’ll get a NoteListException.
from babs import Note, NoteList
class Mock(NoteList):
pass
m = Mock()
# NoteListException "Invalid notes given."
If you need to create an “invalid” NoteList you can use strict parameter.
m = Mock(strict=False)
print(len(m.notes)) # 0
If you set strict to False you can also pass an invalid Note to NoteList.
m = Mock('invalid', 'notes', strict=False)
print(len(m.notes)) # 3
notes attribute¶
You can only get the notes attribute but you can’t set it!
m = Mock(strict=False)
m.notes = [Note(name='C'), Note(name='E'), Note(name='G'), Note(name='C', octave=5)]
# AttributeError: can't set attribute
add note¶
You can use this method if you need to add a Note to the current list.
m = Mock(Note(name='C'), Note(name='D'), Note(name='C'))
c.add_note(note=Note(name='E'))
print(len(c.notes)) # 4
for n in c.notes:
print(n)
# C4
# D4
# C4
# E4
By default strict is set to True, so if you try to add an invalid Note you will get a NoteListException
m.add_note('invalid') # Add a string instead of a Note
# NoteListException: Instance of Note expected, str given.
m = Mock(Note(name='C'), Note(name='D'))
m.add_note('invalid', strict=False)
print(len(m.notes)) # 3
remove note¶
If you need to remove a Note you can use the remove_note() method. You can remove a note by Note(), name, frequency or octave.
m = Mock(Note(name='C'), Note(name='E'), Note(name='G'))
c.remove_note(note=Note(name='G'))
print(len(m.notes)) # 2
for n in m.notes:
print(n)
# C4
# E4
By default, as before, strict is set to True, so if the list will be invalid after remove you will have a NoteListException. If a NoteListException is raised the notes in the list will be restored as they were before the remove.
m = Mock(Note(name='C'))
m.remove_note(note=Note(name='C'))
# Invalid Mock.
print(len(c.notes)) # 1
Removing a Note by octave or name can remove multiple notes.
m = Mock(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='C', octave=5))
print(len(m.notes)) # 4
m.remove_note(name='C')
print(len(m.notes)) # 2
for n in m.notes:
print(n)
# E4
# G4
m = Mock(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='C', octave=5))
m.remove_note(octave=4)
print(len(m.notes)) # 1
for n in m.notes:
print(n)
# C5
is valid¶
If you need to know if the actual list is valid you can use is_valid method. A NoteList is valid if has one or more notes and if all notes are valid Note object (instance of Note)
Comparison¶
NoteList support equal and not equal comparison operator. Two NoteList are the same if they have the same notes (check note comparison for more details). The strict attribute in create doesn’t affect the list comparison.
Mock(Note(name='A'), Note(name='C')) == Mock(Note(name='A'), Note(name='C')) # True
Mock(Note(name='A'), Note(name='C'), strict=True) == Mock(Note(name='A'), Note(name='C'), strict=False) # True
Mock(Note(name='A'), Note(name='C')) == Mock(Note(name='A'), Note(name='C'), Note(name='E')) # False
Mock(Note(name='A'), Note(name='C')) != Mock(Note(name='A'), Note(name='C')) # False
get_notes_from_root¶
You can easily get a list of notes from a root chord using the get_notes_from_root classmethod. Suppose you want to get a basic list of note C - E - G.
notes = Mock.get_notes_from_root(root=Note(name='C'), note_list_type=[4, 7])
for n in c.notes:
print(n)
# C4
# E4
# G4
That’s it, you’ve got a C - E - G list. So how it works? get_notes_from_root use a note_list_type, which is a list of notes distance from root note. So the [4, 7]. 4 is the distance between root from 3d and between the root and the 5th. The distance is based on the Note.NOTES list: NOTES = [‘C’, ‘C#/Db’, ‘D’, ‘D#/Eb’, ‘E’, ‘F’, ‘F#/Gb’, ‘G’, ‘G#/Ab’, ‘A’, ‘A#/Bb’, ‘B’] So let’s say we want a major seven chord.
notes = Mock.get_notes_from_root(root=Note(name='C'), note_list_type=[4, 7, 11])
for n in notes:
print(n)
# C4
# E4
# G4
# B4
This works because the index the E is distant 4 elements from the root (C) in the Note.NOTES list, the G is distant 7 elements and the B is distant 11 elements By default the octave of other notes will be the same as the root note. To change that behaviour you can use the octave param. The root note will not be affected by the octave param. octave could be :
- an integer, so that every note will have that specific octave.
notes = Mock.get_notes_from_root(root=Note(name='C'), note_list_type=[2, 4], octave=3)
for n in notes:
print(n)
# C4
# D3
# E3
- a string ‘root’ NoteList.OCTAVE_TYPE_ROOT or ‘from_root’ NoteList.OCTAVE_TYPE_FROM_ROOT:
- ‘root’, the default behaviour, use the root.octave.
- ‘from_root’ use the root.octave as the starting octave. So if you have a G-B-D, the starting octave is 4 so we have a G4, then we have a B4 and at least the D Note goes to the next octave so it is a D5.
notes = NoteList.get_notes_from_root(root=Note(name='G'), note_list_type=[4, 7], octave=NoteList.OCTAVE_TYPE_FROM_ROOT)
for n in notes:
print(n)
# G4
# B4
# D5
- a callable, that must return an integer. In the callable you have access to root_octave, i (the idx of list distance iteration, starting from 0) and the distance between the current note and the root note. So suppose you want to have a list that looks like G4, B5, D6.
notes = NoteList.get_notes_from_root(
root=Note(name='G'),
note_list_type=[4, 7], octave=lambda root_octave, i, distance: root_octave + i + 1
)
for n in notes:
print(n)
# G4
# B5
# D6
If the octave is invalid, for example a string different from ‘root’ and ‘from_root’ or a float number, it will be set to 4.
You can also specify the alteration of the notes using the alt param (by default is ‘sharp’ Note.SHARP) that works in the same way as for single note.
notes = NoteList.get_notes_from_root(root=Note(name='G'), note_list_type=[4, 7, 11], alt=Note.SHARP)
for n in notes:
print(n)
# G4
# B4
# D4
# F#4
notes = NoteList.get_notes_from_root(root=Note(name='G'), note_list_type=[4, 7, 11], alt=Note.FLAT)
for n in notes:
print(n)
# G4
# D4
# B4
# Gb4
Chord¶
-
class
Chord
(*notes, **kwargs)¶ Return a Chord, an harmonic set of pitches consisting of two or more notes. Chord is an ordered list of notes from lower to higher. If strict is True (default) raise ChordException if chord has less then two notes or if Notes are not valid Note object.
Chord extends NoteList so it inherits all methods from NoteList: is_valid(), add_note(note[, strict=True]), remove_note(note=None, freq=None, name=None, octave=None[, strict=True]).
-
classmethod
create_from_root
(root[, chord_type=None, octave='root', alt='sharp'])¶ -
Create and return a Chord from the root note
-
classmethod
Create your first chord¶
from babs import Note, Chord
c = Chord(Note(name='C'), Note(name='E'), Note(name='G'))
Now you have create the C chord and you can access to the notes attribute.
for n in c.notes:
print(n)
# C4
# E4
# G4
Chord is an ordered list of notes from lower to higher. So the order in which you pass the notes in the constructor is not relevant, the list will always be from lower note (lower frequency) to the higher note (higher frequency).
c = Chord(Note(name='E'), Note(name='G'), Note(name='C'))
for n in c.notes:
print(n)
# C4
# E4
# G4
c = Chord(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='C', octave=3))
for n in c.notes:
print(n)
# C3
# C4
# E4
# G4
strict¶
As we said a Chord consists of two or more note. So what happen if we create a one Note or an empty Chord?
c = Chord(Note(name='C'))
ChordException (Invalid Chord.) You can disable is_valid() control passing strict=False. In this way you will also disable the ordering, because order() works with Note object (using the attribute freq of the note) and will raise AttributeError if the object is not a valid Note.
c = Chord(Note(name='C'), strict=False)
print(len(c.notes)) # 1
If you set strict to False you also disable Note check so this will not raise an exception.
c = Chord('a', 'b', 'c', strict=False)
print(len(c.notes)) # 3
notes attribute¶
You can only get the notes attribute but not set it!
c = Chord(Note(name='C'), Note(name='E'))
c.notes = [Note(name='C'), Note(name='E'), Note(name='G'), Note(name='Bb')]
# AttributeError: can't set attribute
add note¶
This method use the add_note() method of NoteList abstract class but re-order the notes (if Chord is valid) after the note is added.
c = Chord(Note(name='C'), Note(name='E'), Note(name='G'))
c.add_note(note=Note(name='Bb'))
print(len(c.notes)) # 4
for n in c.notes:
print(n)
# C4
# E4
# G4
# Bb4
c.add_note(note=Note(name='C', octave=3))
print(len(c.notes)) # 5
for n in c.notes:
print(n)
# C3
# C4
# E4
# G4
# Bb4
You can add the same note multiple times:
c = Chord(Note(name='A', octave=3), Note(name='C'), Note(name='E'))
c.add_note(note=Note(name='E'))
print(len(c.notes))
for n in c.notes:
print(n)
# A3
# C4
# E4
# E4
By default strict is set to True, so if you add an invalid Note you will get a ChordException
c = Chord(Note(name='C'), Note(name='E'), Note(name='G')).add_note(note='c') # Add a string instead of a Note
# ChordException: Instance of Note expected, str given.
c = Chord(strict=False)
c.add_note(note='c', strict=False)
print(len(c.notes)) # 1
remove note¶
This method use the remove_note() method of NoteList abstract class but re-order the notes (if Chord is valid) after the note is added.
c = Chord(Note(name='C'), Note(name='E'), Note(name='G'))
c.remove_note(note=Note(name='G'))
print(len(c.notes)) # 2
for n in c.notes:
print(n)
# C4
# E4
By default, as before, strict is set to True, so if the Chord will be invalid after remove you will have a ChordException. If ChordException is raised the notes in the chord will be restored as they were before the remove.
c = Chord(Note(name='C'), Note(name='E'))
c.remove_note(note=Note(name='E'))
# Invalid Chord.
print(len(c.notes)) # 2
for n in c.notes:
print(n)
# C4
# E4
Removing a Note by octave or name can remove multiple notes.
c = Chord(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='C', octave=5))
print(len(c.notes)) # 4
c.remove_note(name='C')
print(len(c.notes)) # 2
for n in c.notes:
print(n)
# E4
# G4
c = Chord(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='C', octave=5))
c.remove_note(octave=4, strict=False)
print(len(c.notes)) # 1
for n in c.notes:
print(n)
# C5
is valid¶
If you need to know if the actual Chord is valid you can use is_valid method. A chord is valid if has two or more Note and if all notes are instance of Note()
Comparison¶
Chord support equal and not equal comparison operator. Check NoteList documentation for more information
Create from root Note¶
You can easily create a Chord from root note using the create_from_root classmethod. Suppose you want create a C major chord.
c = Chord.create_from_root(root=Note(name='C'))
for n in c.notes:
print(n)
# C4
# E4
# G4
That’s it, you’ve got a C major chord. create_from_root use the classmethod get_notes_from_root of NoteList. Check NoteList documentation for more information.
babs come with some of pre-defined chord_type so that the previous example could be the same as
c = Chord.create_from_root(root=Note(name='C'), chord_type=Chord.MAJOR_SEVEN_TYPE)
You can use a custom list or use some of the pre-defined chord type.
List of pre-defined chord type¶
Chord type |
---|
MAJOR_TYPE |
MAJOR_SEVEN_TYPE |
MINOR_TYPE |
MINOR_SEVEN_TYPE |
DOMINANT_TYPE |
MINOR_MAJOR_SEVEN_TYPE |
HALF_DIMINISHED_SEVEN_TYPE |
DIMINISHED_TYPE |
DIMINISHED_SEVEN_TYPE |
AUGMENTED_TYPE |
AUGMENTED_SEVEN_TYPE |
AUGMENTED_MAJOR_SEVEN_TYPE |
MAJOR_SIXTH_TYPE |
MINOR_SIXTH_TYPE |
SUS4_TYPE |
SUS4_SEVEN_TYPE |
SUS4_MAJOR_SEVEN_TYPE |
SUS2_TYPE |
SUS2_SEVEN_TYPE |
SUS2_MAJOR_SEVEN_TYPE |
Scale¶
-
class
Scale
(*notes, **kwargs)¶ Return a Scale, a set of musical notes ordered by fundamental frequency or pitch. Scale is an ordered list of unique notes. If strict is True (default) raise ScaleException if Notes are not valid Note object.
Scale extends NoteList so it inherits all methods from NoteList: is_valid(), add_note(note[, strict=True]), remove_note(note=None, freq=None, name=None, octave=None[, strict=True]).
-
classmethod
create_from_root
(root[, scale_type=None, octave='root', alt='sharp'])¶ -
Create and return a Scale from the root note
-
classmethod
Create your first scale¶
from babs import Note, Scale
s = Scale(Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'), Note(name='B'))
Now you have create the C major scale and you can access to the notes attribute.
for n in s.notes:
print(n)
# C4
# D4
# E4
# F4
# G4
# A4
# B4
Scale is an ordered list of unique notes. Scale could be ascending (from lower to higher) or descending (from higher to lower), by default is ascending. The order in which you pass the notes in the constructor is not relevant, the list will always be from lower to higher (frequency) or from higher to lower (frequency) note.
s = Scale(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='A'), Note(name='F'), Note(name='D'), Note(name='B'))
for n in s.notes:
print(n)
# C4
# D4
# E4
# F4
# G4
# A4
# B4
s = Scale(Note(name='C'), Note(name='E'), Note(name='G'), Note(name='A'), Note(name='F'), Note(name='D'), Note(name='B'), order=Scale.DESCENDING_SCALE_TYPE)
for n in s.notes:
print(n)
# B4
# A4
# G4
# F4
# E4
# D4
# C4
strict¶
As we said a Scale is a set of unique notes. So what happen if we create an empty Scale?
s = Scale()
ScaleException (Invalid Scale.) You can disable is_valid() control passing strict=False. In this way you will also disable the ordering, because order() works with Note object (using the attribute freq of the note) and will raise AttributeError if the object is not a valid Note.
s = Scale(strict=False)
print(len(s.notes)) # 0
If you set strict to False you also disable Note check so this will not raise an exception.
s = Scale('a', 'b', 'c', strict=False)
print(len(c.notes)) # 3
notes attribute¶
You can only get the notes attribute but not set it!
s = Scale(Note(name='C'))
s.notes = [Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'), Note(name='B')]
# AttributeError: can't set attribute
add note¶
This method use the add_note() method of NoteList abstract class but re-order the notes (if Scale is valid) after the note is added. It also checks if the note alredy exists in the scale and raise an exception if it alredy exists.
s = Scale(Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'))
s.add_note(note=Note(name='B'))
print(len(s.notes)) # 7
for n in s.notes:
print(n)
# C4
# D4
# E4
# F4
# G4
# A4
# B4
s.add_note(note=Note(name='B'))
# babs.exceptions.scale_exception.ScaleException: Note B4 is alredy in Scale.
By default strict is set to True, so if you add an invalid Note or a note that alredy exists in the scale you will get a ScaleException
s = Scale(Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'))
s.add_note(note='c') # Add a string instead of a Note
# ScaleException: AttributeError: 'str' object has no attribute 'freq'
remove note¶
This method use the remove_note() method of NoteList abstract class but re-order the notes (if Scale is valid) after the note is added.
s = Scale(Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'), Note(name='B'))
s.remove_note(note=Note(name='B'))
print(len(s.notes)) # 6
for n in s.notes:
print(n)
# C4
# D4
# E4
# F4
# G4
# A4
By default, as before, strict is set to True, so if the Scale will be invalid after remove you will have a ScaleException. If ScaleException is raised the notes in the scale will be restored as they were before the remove.
s = Scale(Note(name='C'))
s.remove_note(note=Note(name='C'))
# Invalid Scale.
print(len(s.notes)) # 1
for n in s.notes:
print(n)
# C4
Removing a Note by octave or name can remove multiple notes.
s = Scale(Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'), Note(name='B'), Note(name='C', octave=5))
# C4 and C5 are different note
print(len(s.notes)) # 8
s.remove_note(name='C')
print(len(s.notes)) # 6
for n in s.notes:
print(n)
# D4
# E4
# F4
# G4
# A4
# B4
s = Scale(Note(name='C'), Note(name='D'), Note(name='E'), Note(name='F'), Note(name='G'), Note(name='A'), Note(name='B'), Note(name='C', octave=5), Note(name='C', octave=6))
s.remove_note(octave=5)
print(len(s.notes)) # 7
for n in s.notes:
print(n)
# C4
# D4
# E4
# F4
# G4
# A4
# B4
is valid¶
If you need to know if the actual Scale is valid you can use is_valid method. A scale is valid if has one or more Note and if all notes are instance of Note()
Comparison¶
Scale support equal and not equal comparison operator. Check NoteList documentation for more information
Create Scale from root Note¶
You can easily create a Scale from root note using the create_from_root classmethod. Suppose you want create a C major scale.
s = Scale.create_from_root(root=Note(name='C'))
for n in s.notes:
print(n)
# C4
# D4
# E4
# F4
# G4
# A4
# B4
s = Scale.create_from_root(root=Note(name='C'), scale_type=Scale.MINOR_TYPE, alt=Note.FLAT)
for n in s.notes:
print(n)
# C4
# D4
# Eb4
# F4
# G4
# Ab4
# Bb4
That’s it, you’ve got a C major scale and then a C minor scale. create_from_root use the classmethod get_notes_from_root of NoteList. Check NoteList documentation for more information.
babs come with some of pre-defined scale_type so that the previous example could be the same as
s = Scale.create_from_root(root=Note(name='C'), chord_type=Scale.DORIAN_TYPE)
You can use a custom list or use some of the pre-defined chord type.
List of pre-defined scale type¶
Scale type |
---|
MAJOR_TYPE |
MINOR_TYPE |
IONIAN_TYPE |
DORIAN_TYPE |
PHRIGIAN_TYPE |
LIDYAN_TYPE |
DOMINANT_TYPE |
AEOLIAN_TYPE |
LOCRIAN_TYPE |
PENTATONIC_TYPE |
PENTATONIC_MINOR_TYPE |
BLUES_TYPE |
BLUES_MINOR_TYPE |
MELODIC_MINOR_TYPE |
HARMONIC_MINOR_TYPE |
HARMONIC_MAJOR_TYPE |
Authors¶
- Mattia Careddu - http://github.com/iskyd