munotes

musical-notes

A library for handling notes and chords and their sounds in Python. An object can be created by inputting the name of a note or chord. From the object, various waveforms can be generated and sounds can be played back on the notebook. They can also be managed as a sequence of objects.

source: misya11p/munotes

Supported classes:

notes

Module for handling musical notes.

class munotes.notes.Note(query, octave=4, waveform='sin', duration=1.0, unit='s', bpm=120, envelope=None, duty=0.5, width=1.0, amp=1.0, sr=22050, A4=440.0)

Bases: BaseNotes

Note class. Single note. It can be initialized with note name or MIDI note number.

Parameters
  • query (Union[str, int]) – String of note name or midi note number. If string is given, valid string pattern is ‘[A-Ga-g][#♯+b♭-]?d*’. Ex: ‘C’, ‘C#’, ‘Cb’, ‘C4’

  • octave (int, optional) – Octave of the note. This argument is ignored if octave is specified in the note name string, or if query is int. Defaults to 4.

  • waveform (Union[str, Callable], optional) – Waveform type. This value becomes the default value when render() and play(). Spported waveform types are ‘sin’, ‘square’, ‘sawtooth’, ‘triangle’ and user-defined waveform function. user-defined waveform function must take time axis as an argument and return an array like waveform of the same length. Defaults to ‘sin’.

  • duration (float, optional) – Duration. This value becomes the default value when rendering the waveform. Defaults to 1..

  • unit (str, optional) – Unit of duration. This value becomes the default value when rendering the waveform. Supported units are ‘s’: seconds, ‘ms’: milliseconds and ‘ql’: quarter length (bpm is required) Defaults to ‘s’.

  • bpm (float, optional) – BPM (beats per minute). If unit is not ‘ql’, this argument is ignored. This value becomes the default value when rendering the waveform. Defaults to 120.

  • envelope (Envelope, optional) – Envelope of the note. This value becomes the default value when rendering the waveform. Defaults to Envelope() with attack=0., decay=0., sustain=1., release=0., hold=0..

  • duty (float, optional) – Duty cycle for when waveform is ‘square’. This value becomes the default value when rendering the waveform. Defaults to 0.5.

  • width (float, optional) – Width for when waveform is ‘sawtooth’. This value becomes the default value when rendering the waveform. Defaults to 1..

  • amp (float, optional) – Amplitude. This value becomes the default value when rendering the waveform. Defaults to 1..

  • sr (int, optional) – Sampling rate. This value becomes the default value when rendering the waveform. Defaults to 22050.

  • A4 (float, optional) – tuning. freqency of A4. Defaults to 440..

Attributes:
  • name (str): note name

  • octave (int): octave of the note

  • idx (int): index of the note name when C as 0

  • num (int): MIDI note number

  • freq (float): frequency of the note

  • waveform (Union[str, Callable]): default waveform type

  • duration (float): default duration

  • unit (str): default unit of duration

  • bpm (float): default BPM

  • envelope (Envelope): default envelope

  • duty (float): default duty

  • width (float): default width

  • amp (float): default amplitude

  • sr (int): default sampling rate

  • A4 (float): tuning. freqency of A4

Examples

>>> import munotes as mn
>>> note = mn.Note("C4")
>>> print(note)
C4

You can also input note name and octave separately.

>>> note = mn.Note("C", 4)
>>> print(note)
C4

You can also input MIDI note number as an integer.

>>> note = mn.Note(60)
>>> print(note)
C4
property name
property idx
property octave
property num
property freq
transpose(n_semitones)

Transpose note.

Parameters

n_semitones (int) – Number of semitones to transpose.

Examples

>>> note = mn.Note("C4")
>>> note.transpose(1)
>>> print(note)
C#4
tuning(freq=440.0, stand_A4=True)

Tuning.

Parameters
  • freq (float, optional) – Freqency of the note or A4. Defaults to 440..

  • stand_A4 (bool, optional) – If True, the tuning standard is A4. If False, the note frequency is changed to freq.

Examples

>>> note = mn.Note("C4")
>>> print(note.freq)
>>> note.tuning(450.)
>>> print(note.freq)
261.6255653005986
267.5716008756122
>>> note = mn.Note("C4")
>>> print(note.freq)
>>> note.tuning(270., stand_A4=False)
>>> print(note.freq)
261.6255653005986
270.0
render(waveform=None, duration=None, unit=None, bpm=None, envelope=None, duty=None, width=None, amp=None)

Rendering waveform of the note. If an argument is not specified, its attribute value set on initialization is used as the default value.

Returns

Waveform of the note.

Return type

np.ndarray

Examples

>>> note = mn.Note("C4")
>>> note.render('sin')
array([ 0.        ,  0.07448499,  0.14855616, ..., -0.59706869,
       -0.65516123, -0.70961388])
>>> note.render(lambda t: np.sin(t) + np.sin(2*t))
array([0.        , 0.23622339, 0.46803688, ..., 1.75357961, 1.72041279,
       1.66076322])
class munotes.notes.Rest(duration=1.0, unit='s', bpm=120)

Bases: Note

Rest class for Track and Stream class. Return zeros array when rendering.

Examples

>>> rest = mn.Rest()
>>> rest.sin()
array([0., 0., 0., ..., 0., 0., 0.])
class munotes.notes.Notes(notes, waveform='sin', duration=1.0, unit='s', bpm=120, envelope=None, duty=0.5, width=1.0, amp=1.0, sr=22050, A4=440.0)

Bases: Note

Notes class. Manage multiple notes at once. Default attributes (waveform, duration, unit, bpm, sr, A4) set in each Note are ignored and the attributes set in this class are used.

Similar to the Note class, it is possible to generate waveforms using render() and sin().

Parameters
  • notes (List[Union[Note, int, str]]) –

    List of notes. Supported note types:
    • Note: mn.Note, mn.Notes, etc.

    • str: note name.

    • int: midi note number.

  • amp (float, optional) – Amplitude of each note in the Notes. Note that this value is not amplitude of this Notes. Defaults to 1..

Attributes:
  • notes (List[Note]): list of notes

  • names (List[str]): list of note names

  • fullnames (List[str]): list of note fullnames

  • nums (List[int]): list of MIDI note numbers

Examples

>>> import munotes as mn
>>> notes = mn.Notes([
>>>     mn.Note("C4"),
>>>     mn.Note("E4"),
>>>     mn.Note("G4"),
>>> ])
>>> notes
Notes (notes: Note C4, Note E4, Note G4)
>>> notes = mn.Notes(["C4", "E4", "G4"])
>>> notes
Notes (notes: Note C4, Note E4, Note G4)
>>> notes = mn.Notes([60, 64, 67])
>>> notes
Notes (notes: Note C4, Note E4, Note G4)
>>> notes = mn.Notes([60, 64, 67]) + mn.Note("C5")
>>> notes
Notes (notes: Note C4, Note E4, Note G4, Note C5)
append(*note)

Append notes.

Parameters

note (Union[Note, int]) – Note (or Notes or Chord) or midi note number

Examples

>>> notes = mn.Notes(mn.Note("C4"))
>>> notes = notes.append(mn.Note("E4"), mn.Note("G4"))
>>> notes
Notes (notes: Note C4, Note E4, Note G4)
class munotes.notes.Chord(chord_name, type=None, octave=4, waveform='sin', duration=1.0, unit='s', bpm=120, envelope=None, duty=0.5, width=1.0, amp=1.0, sr=22050, A4=440.0)

Bases: Notes

Chord class. Estimating notes from chord names and creating a Notes object.

Supported chord names are shown in mn.chord_names. mn.chord_names is a dictionary of chord names and intervals between notes with the root note as 0. Ex: {‘’: (0, 4, 7), ‘m’: (0, 3, 7), ‘dim7’: (0, 3, 6, 9), …}. You can add your own chord names and intervals to this dictionary.

Parameters
  • chord_name (str) – string of chord name. Chord type in the string is ignored if ‘type’ argument is specified.

  • type (str, optional) – chord type. Ex. ‘’, ‘m7’, ‘7’, ‘sus4’.

  • octave (int, optional) – octave of the root note to initialize notes.

Attributes:
  • name (str): chord name

  • root (Note): root note.

  • interval (tuple):

    interval of the chord. Ex: (0,4,7) for C major

  • type (str): chord type. Ex: “m” for C minor

  • names (tuple): note names of the chord.

  • notes (List[Note]): notes of the chord.

  • idxs (int): index of the root note.

Examples

>>> import munotes as mn
>>> chord = mn.Chord("C")
>>> chord.names
['C', 'E', 'G']

Adding arbitrary chords.

>>> mn.chord_names["black"] = (0, 1, 2, 3, 4)
>>> chord = mn.Chord("C", "black")
>>> chord.names
['C', 'C#', 'D', 'D#', 'E']
transpose(n_semitones)

Transpose chord

Examples

>>> chord = mn.Chord("C")
>>> chord.transpose(1)
>>> chord.names
['C#', 'F', 'G#']

sequence

Module for managing notes as sequences.

class munotes.sequence.Track(sequence, waveform=None, duration=None, unit=None, bpm=None, envelope=None, duty=None, width=None, amp=None, sr=22050, A4=440.0)

Bases: BaseNotes

Track class. Manage multiple notes as a sequence. If inputed specific arguments or set default attributes, these apply to all notes in the sequence when rendering. If not, each note will be rendered with its own attributes.

Similar to the Note class, it is possible to generate waveforms using render() and sin().

Parameters
  • sequence (List[Note]) – sequence of notes.

  • envelope (Envelope, optional) – Envelope of the track notes. Defaults to Envelope() with attack=0.01, decay=0., sustain=1., release=0.01, hold=0..

  • amp (float, optional) – Amplitude of each note in the Track. Note that this value is not amplitude of this Track. Defaults to None.

Attributes:
  • sequence (List[Note]): sequence of notes.

Examples

>>> import munotes as mn
>>> track = mn.Track([
>>>     mn.Note("C4"),
>>>     mn.Note("D4"),
>>>     mn.Note("E4"),
>>>     mn.Chord("C"),
>>> ])
>>> track
Track (notes: Note C4, Note D4, Note E4, Note C4, Note E4, Note G4)
>>> track.sin()
array([ 0.        ,  0.07448499,  0.14855616, ..., -0.01429455,
    -0.00726152, -0.        ])
append(*notes)

Append notes to the track.

Parameters

*notes (Note) – notes to append

Example

>>> track = mn.Track([
>>>     mn.Note("C4", duration=1),
>>>     mn.Note("D4", duration=1),
>>> ])
>>> track.append(mn.Note("E4", duration=1))
Track (notes: Note C4, Note D4, Note E4)
class munotes.sequence.Stream(tracks, waveform=None, duration=None, unit=None, bpm=None, envelope=None, duty=None, width=None, amp=None, sr=22050, A4=440)

Bases: BaseNotes

Stream class. Manage multiple tracks as a stream.

Parameters
  • tracks (List[Track]) – tracks

  • amp (float, optional) – Amplitude of each note in the Stream. Note that this value is not amplitude of this Stream. Defaults to None.

Attributes:
  • tracks (List[Track]): tracks

Example

>>> melody = mn.Track([
>>>     mn.Note("C4"),
>>>     mn.Note("D4"),
>>>     mn.Note("E4"),
>>> ])
>>> chords = mn.Track([mn.Chord("C", duration=3)])
>>> stream = mn.Stream([melody, chords])
>>> stream
Stream (notes: Note C4, Note D4, Note E4, Note C4, Note E4, Note G4)
>>> stream.render('sin')
array([ 0.        ,  0.35422835,  0.70541282, ..., -0.02489362,
       -0.01173826,  0.        ])
>>> stream.render([
>>>     'square',
>>>     lambda t: np.sin(t) + np.sin(2*t)
>>> ])
array([ 1.        ,  1.83660002,  2.64969075, ..., -0.05431521,
       -0.02542138,  0.        ])