CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-mingus

Python music theory and MIDI processing library for programmers, musicians, composers, and researchers.

Pending
Overview
Eval results
Files

musical-containers.mddocs/

Musical Containers

Data structures for representing and manipulating musical information at different hierarchical levels - from individual notes to complete compositions. These classes store and organize musical data for analysis, manipulation, and playback.

Capabilities

Note Class

Represents a single musical note with pitch, octave, dynamics, and MIDI properties.

class Note:
    """Single musical note with pitch and performance attributes."""
    
    def __init__(self, name: str = "C", octave: int = 4, dynamics: Any = None, velocity: int = None, channel: int = None):
        """
        Create Note object.
        
        Parameters:
        - name: Note name (e.g., "C", "F#", "Bb")
        - octave: Octave number (typically 0-9)
        - dynamics: Dynamic marking (pp, p, mp, mf, f, ff, etc.)
        - velocity: MIDI velocity (0-127)
        - channel: MIDI channel (1-16)
        """
    
    @property
    def name(self) -> str:
        """Note name (e.g., "C#")."""
    
    @property
    def octave(self) -> int:
        """Octave number."""
    
    @property
    def dynamics(self) -> Any:
        """Dynamic marking."""
    
    @property
    def velocity(self) -> int:
        """MIDI velocity (0-127)."""
    
    @property
    def channel(self) -> int:
        """MIDI channel (1-16)."""
    
    def set_note(self, name: str = "C", octave: int = 4, dynamics: Any = None, velocity: int = None, channel: int = None) -> None:
        """
        Set note properties.
        
        Parameters:
        - name: Note name
        - octave: Octave number
        - dynamics: Dynamic marking
        - velocity: MIDI velocity
        - channel: MIDI channel
        """
    
    def empty(self) -> None:
        """Clear note to default values."""
    
    def augment(self) -> None:
        """Augment note (raise by semitone)."""
    
    def diminish(self) -> None:
        """Diminish note (lower by semitone)."""
    
    def transpose(self, interval: str, up: bool = True) -> None:
        """
        Transpose note by interval.
        
        Parameters:
        - interval: Interval to transpose (e.g., "3", "5", "b7")
        - up: Direction (True for up, False for down)
        """
    
    def change_octave(self, diff: int) -> None:
        """
        Change octave by difference.
        
        Parameters:
        - diff: Octave difference (positive or negative)
        """
    
    def octave_up(self) -> None:
        """Move up one octave."""
    
    def octave_down(self) -> None:
        """Move down one octave."""
    
    def to_hertz(self, standard_pitch: float = 440) -> float:
        """
        Convert to frequency in Hz.
        
        Parameters:
        - standard_pitch: A4 frequency reference
        
        Returns:
        Frequency in Hz
        """
    
    def from_hertz(self, hertz: float, standard_pitch: float = 440) -> None:
        """
        Set note from frequency.
        
        Parameters:
        - hertz: Frequency in Hz
        - standard_pitch: A4 frequency reference
        """
    
    def measure(self, other: 'Note') -> int:
        """
        Measure interval to other note in half steps.
        
        Parameters:
        - other: Other Note object
        
        Returns:
        Interval in half steps
        """
    
    def to_shorthand(self) -> str:
        """
        Convert to shorthand notation.
        
        Returns:
        Shorthand notation string
        """
    
    def from_shorthand(self, shorthand: str) -> None:
        """
        Set from shorthand notation.
        
        Parameters:
        - shorthand: Shorthand notation string
        """

NoteContainer Class

Container for holding multiple notes, representing chords, intervals, or simultaneous note combinations.

class NoteContainer:
    """Container for multiple notes (chords, intervals)."""
    
    def __init__(self, notes: List[Union[str, Note]] = None):
        """
        Create NoteContainer.
        
        Parameters:
        - notes: List of note names or Note objects
        """
    
    def empty(self) -> None:
        """Empty container of all notes."""
    
    def add_note(self, note: Union[str, Note], octave: int = None, dynamics: Any = None) -> bool:
        """
        Add note to container.
        
        Parameters:
        - note: Note name or Note object
        - octave: Octave for note name
        - dynamics: Dynamic marking
        
        Returns:
        True if note was added successfully
        """
    
    def add_notes(self, notes: List[Union[str, Note]]) -> None:
        """
        Add multiple notes to container.
        
        Parameters:
        - notes: List of note names or Note objects
        """
    
    def remove_note(self, note: Union[str, Note], octave: int = -1) -> bool:
        """
        Remove note from container.
        
        Parameters:
        - note: Note name or Note object to remove
        - octave: Specific octave to remove (-1 for any)
        
        Returns:
        True if note was removed
        """
    
    def remove_notes(self, notes: List[Union[str, Note]]) -> None:
        """
        Remove multiple notes from container.
        
        Parameters:
        - notes: List of notes to remove
        """
    
    def from_chord(self, shorthand: str) -> bool:
        """
        Create container from chord shorthand.
        
        Parameters:
        - shorthand: Chord shorthand (e.g., "CM7", "Am", "F#dim")
        
        Returns:
        True if chord was created successfully
        """
    
    def from_interval(self, startnote: str, shorthand: str, up: bool = True) -> bool:
        """
        Create container from interval.
        
        Parameters:
        - startnote: Starting note
        - shorthand: Interval shorthand (e.g., "3", "5", "b7")
        - up: Direction (True for up, False for down)
        
        Returns:
        True if interval was created successfully
        """
    
    def determine(self, shorthand: bool = False) -> str:
        """
        Determine chord name.
        
        Parameters:
        - shorthand: Return shorthand notation
        
        Returns:
        Chord name or description
        """
    
    def sort(self) -> None:
        """Sort notes by pitch (lowest to highest)."""
    
    def transpose(self, interval: str, up: bool = True) -> None:
        """
        Transpose all notes by interval.
        
        Parameters:
        - interval: Interval to transpose
        - up: Direction (True for up, False for down)
        """
    
    def augment(self) -> None:
        """Augment all notes."""
    
    def diminish(self) -> None:
        """Diminish all notes."""
    
    def is_consonant(self, include_fourths: bool = True) -> bool:
        """
        Test if container contains consonant intervals.
        
        Parameters:
        - include_fourths: Include perfect fourths as consonant
        
        Returns:
        True if all intervals are consonant
        """
    
    def is_dissonant(self, include_fourths: bool = False) -> bool:
        """
        Test if container contains dissonant intervals.
        
        Parameters:
        - include_fourths: Include perfect fourths as dissonant
        
        Returns:
        True if any intervals are dissonant
        """
    
    def get_note_names(self) -> List[str]:
        """
        Get list of note names.
        
        Returns:
        List of note names in container
        """
    
    def remove_duplicate_notes(self) -> None:
        """Remove duplicate notes from container."""

Bar Class

Represents a musical bar/measure containing notes with durations and timing information.

class Bar:
    """Musical bar/measure with notes and timing."""
    
    def __init__(self, key: str = "C", meter: Tuple[int, int] = (4, 4)):
        """
        Create Bar object.
        
        Parameters:
        - key: Key signature
        - meter: Time signature (numerator, denominator)
        """
    
    @property
    def key(self) -> str:
        """Key signature."""
    
    @property
    def meter(self) -> Tuple[int, int]:
        """Time signature tuple."""
    
    def empty(self) -> None:
        """Empty bar of all notes."""
    
    def set_meter(self, meter: Tuple[int, int]) -> None:
        """
        Set time signature.
        
        Parameters:
        - meter: Time signature tuple
        """
    
    def place_notes(self, notes: Union[str, List[str], Note, NoteContainer], duration: int) -> bool:
        """
        Place notes with duration in bar.
        
        Parameters:
        - notes: Notes to place (various formats accepted)
        - duration: Note duration (1=whole, 2=half, 4=quarter, etc.)
        
        Returns:
        True if notes were placed successfully
        """
    
    def place_notes_at(self, notes: Union[str, List[str], Note, NoteContainer], at: float) -> bool:
        """
        Place notes at specific position in bar.
        
        Parameters:
        - notes: Notes to place
        - at: Position in bar (0.0 to 1.0)
        
        Returns:
        True if notes were placed successfully
        """
    
    def place_rest(self, duration: int) -> bool:
        """
        Place rest with duration.
        
        Parameters:
        - duration: Rest duration
        
        Returns:
        True if rest was placed successfully
        """
    
    def is_full(self) -> bool:
        """
        Check if bar is full.
        
        Returns:
        True if bar contains a full measure worth of notes/rests
        """
    
    def space_left(self) -> float:
        """
        Get remaining space in bar.
        
        Returns:
        Remaining space as fraction (0.0 to 1.0)
        """
    
    def value_left(self) -> int:
        """
        Get remaining value in bar.
        
        Returns:
        Remaining note value
        """
    
    def remove_last_entry(self) -> bool:
        """
        Remove last entry from bar.
        
        Returns:
        True if entry was removed
        """
    
    def transpose(self, interval: str, up: bool = True) -> None:
        """
        Transpose all notes in bar.
        
        Parameters:
        - interval: Interval to transpose
        - up: Direction (True for up, False for down)
        """
    
    def augment(self) -> None:
        """Augment all notes in bar."""
    
    def diminish(self) -> None:
        """Diminish all notes in bar."""
    
    def determine_chords(self, shorthand: bool = False) -> List[str]:
        """
        Determine chords in bar.
        
        Parameters:
        - shorthand: Return shorthand notation
        
        Returns:
        List of chord names
        """
    
    def determine_progression(self, shorthand: bool = False) -> List[str]:
        """
        Determine chord progression in bar.
        
        Parameters:
        - shorthand: Return shorthand notation
        
        Returns:
        List of chord progressions
        """
    
    def get_range(self) -> Tuple[Note, Note]:
        """
        Get note range in bar.
        
        Returns:
        Tuple of (lowest_note, highest_note)
        """
    
    def get_note_names(self) -> List[str]:
        """
        Get all note names in bar.
        
        Returns:
        List of note names
        """

Track Class

Represents a musical track containing a sequence of bars, typically for a single instrument or voice.

class Track:
    """Musical track containing sequence of bars."""
    
    def __init__(self, instrument: Any = None):
        """
        Create Track object.
        
        Parameters:
        - instrument: Associated instrument object
        """
    
    @property
    def instrument(self) -> Any:
        """Associated instrument."""
    
    @property
    def name(self) -> str:
        """Track name."""
    
    def add_bar(self, bar: Bar) -> None:
        """
        Add bar to track.
        
        Parameters:
        - bar: Bar object to add
        """
    
    def add_notes(self, note: Union[str, Note, NoteContainer], duration: int = None) -> None:
        """
        Add notes with duration to track.
        
        Parameters:
        - note: Notes to add
        - duration: Note duration
        """
    
    def get_notes(self) -> List[Note]:
        """
        Get all notes in track.
        
        Returns:
        List of all Note objects in track
        """
    
    def from_chords(self, chords: List[str], duration: int = 1) -> None:
        """
        Create track from chord list.
        
        Parameters:
        - chords: List of chord shorthands
        - duration: Duration for each chord
        """
    
    def transpose(self, interval: str, up: bool = True) -> None:
        """
        Transpose entire track.
        
        Parameters:
        - interval: Interval to transpose
        - up: Direction (True for up, False for down)
        """
    
    def augment(self) -> None:
        """Augment all notes in track."""
    
    def diminish(self) -> None:
        """Diminish all notes in track."""
    
    def get_tuning(self) -> Any:
        """
        Get instrument tuning.
        
        Returns:
        Tuning object if instrument has tuning
        """
    
    def set_tuning(self, tuning: Any) -> None:
        """
        Set instrument tuning.
        
        Parameters:
        - tuning: Tuning object
        """
    
    def test_integrity(self) -> bool:
        """
        Test track integrity.
        
        Returns:
        True if track structure is valid
        """

Composition Class

Represents a complete musical composition containing multiple tracks with metadata.

class Composition:
    """Complete musical composition with multiple tracks."""
    
    def __init__(self):
        """Create Composition object."""
    
    @property
    def title(self) -> str:
        """Composition title."""
    
    @property
    def subtitle(self) -> str:
        """Composition subtitle."""
    
    @property
    def author(self) -> str:
        """Author name."""
    
    @property
    def email(self) -> str:
        """Author email."""
    
    def empty(self) -> None:
        """Empty composition of all tracks."""
    
    def reset(self) -> None:
        """Reset composition to initial state."""
    
    def add_track(self, track: Track) -> None:
        """
        Add track to composition.
        
        Parameters:
        - track: Track object to add
        """
    
    def add_note(self, note: Union[str, Note]) -> None:
        """
        Add note to first track.
        
        Parameters:
        - note: Note to add
        """
    
    def set_title(self, title: str = "Untitled", subtitle: str = "") -> None:
        """
        Set composition title and subtitle.
        
        Parameters:
        - title: Main title
        - subtitle: Subtitle
        """
    
    def set_author(self, author: str = "", email: str = "") -> None:
        """
        Set author information.
        
        Parameters:
        - author: Author name
        - email: Author email
        """

Suite Class

Represents a suite containing multiple compositions.

class Suite:
    """Suite containing multiple compositions."""
    
    def __init__(self):
        """Create Suite object."""
    
    def add_composition(self, composition: Composition) -> None:
        """
        Add composition to suite.
        
        Parameters:
        - composition: Composition object to add
        """
    
    def set_author(self, author: str, email: str = "") -> None:
        """
        Set author information.
        
        Parameters:
        - author: Author name
        - email: Author email
        """
    
    def set_title(self, title: str, subtitle: str = "") -> None:
        """
        Set suite title and subtitle.
        
        Parameters:
        - title: Main title
        - subtitle: Subtitle
        """

Instrument Classes

Classes representing various musical instruments with range validation and specific capabilities.

class Instrument:
    """Base instrument class."""
    
    def __init__(self):
        """Create Instrument object."""
    
    def set_range(self, range: Tuple[Note, Note]) -> None:
        """
        Set instrument range.
        
        Parameters:
        - range: Tuple of (lowest_note, highest_note)
        """
    
    def note_in_range(self, note: Note) -> bool:
        """
        Check if note is in instrument range.
        
        Parameters:
        - note: Note to check
        
        Returns:
        True if note is in range
        """
    
    def notes_in_range(self, notes: List[Note]) -> bool:
        """
        Check if all notes are in range.
        
        Parameters:
        - notes: List of notes to check
        
        Returns:
        True if all notes are in range
        """
    
    def can_play_notes(self, notes: List[Note]) -> bool:
        """
        Check if instrument can play notes.
        
        Parameters:
        - notes: List of notes to check
        
        Returns:
        True if instrument can play all notes
        """

class Piano(Instrument):
    """Piano instrument with 88-key range."""
    
    def __init__(self):
        """Create Piano object with standard range."""

class Guitar(Instrument):
    """Guitar instrument with standard tuning."""
    
    def __init__(self):
        """Create Guitar object with standard tuning."""

class MidiInstrument(Instrument):
    """Generic MIDI instrument."""
    
    def __init__(self, name: str = ""):
        """
        Create MIDI instrument.
        
        Parameters:
        - name: Instrument name
        """

class MidiPercussionInstrument(MidiInstrument):
    """MIDI percussion instrument with drum methods."""
    
    def __init__(self):
        """Create MIDI percussion instrument."""
    
    def acoustic_bass_drum(self) -> Note:
        """Return acoustic bass drum note."""
    
    def snare(self) -> Note:
        """Return snare drum note."""
    
    def hi_hat(self) -> Note:
        """Return hi-hat note."""
    
    def crash_cymbal(self) -> Note:
        """Return crash cymbal note."""
    
    def ride_cymbal(self) -> Note:
        """Return ride cymbal note."""
    
    def open_hi_hat(self) -> Note:
        """Return open hi-hat note."""
    
    def closed_hi_hat(self) -> Note:
        """Return closed hi-hat note."""
    
    # Additional percussion methods available...

Usage Examples

Creating and Manipulating Notes

from mingus.containers import Note

# Create notes
note1 = Note("C", 4)  # Middle C
note2 = Note("F#", 5, velocity=80, channel=1)

# Manipulate notes
note1.transpose("5")  # Transpose up a fifth to G
note1.octave_up()     # Move to octave 5

# Convert to frequency
freq = note1.to_hertz()  # Get frequency in Hz
print(f"G5 frequency: {freq} Hz")

Working with Chords

from mingus.containers import NoteContainer

# Create chord from shorthand
chord = NoteContainer()
chord.from_chord("CM7")  # C major 7th chord

# Analyze chord
chord_name = chord.determine()  # Returns chord name
print(f"Chord: {chord_name}")

# Manipulate chord
chord.transpose("2")  # Transpose up a whole step
chord.sort()          # Sort notes by pitch

Building Musical Structures

from mingus.containers import Bar, Track, Composition

# Create a bar with notes
bar = Bar("C", (4, 4))  # 4/4 time in C major
bar.place_notes("C", 4)   # Quarter note C
bar.place_notes(["E", "G"], 4)  # Quarter note E and G together
bar.place_rest(2)         # Half rest

# Create track and composition
track = Track()
track.add_bar(bar)

composition = Composition()
composition.add_track(track)
composition.set_title("Simple Melody")

Install with Tessl CLI

npx tessl i tessl/pypi-mingus

docs

format-export.md

index.md

midi-operations.md

music-theory-core.md

musical-containers.md

tile.json