Score Concept
The Score
class is the central container in Symusic, representing a complete musical piece, analogous to a full score in music notation. It serves as the primary object for loading, manipulating, and saving musical data.
Purpose and Role
The Score
object aggregates all the necessary information to define a piece of music:
- Structure: Holds multiple
Track
objects, typically representing different instruments or voices. - Global Context: Contains events that apply to the entire piece, such as tempo changes, time signatures, and key signatures.
- Metadata: Stores information like markers and the fundamental time resolution (
ticks_per_quarter
).
It acts as the root of the musical data hierarchy and provides methods for operations that affect the entire piece.
See Score API Reference for detailed usage.
Key Components
- Tracks (
tracks
): A list (TrackList
) containingTrack
objects. This is where most note-level data resides. - Tempo Changes (
tempos
): A list (TempoList
) defining the speed of the music over time. - Time Signatures (
time_signatures
): A list (TimeSignatureList
) defining the meter (e.g., 4/4, 3/4) over time. - Key Signatures (
key_signatures
): A list (KeySignatureList
) defining the key (e.g., C major, A minor) over time. - Markers (
markers
): A list (TextMetaList
) for textual annotations at specific time points. - Ticks Per Quarter (
ticks_per_quarter
/tpq
): An integer defining the time resolution in ticks for tick-based time units. Crucial for interpreting MIDI timing.
Time Units Concept
A Score
object (and its contained tracks/events) operates within a specific time unit system: Tick
, Quarter
, or Second
. This is a core concept explained in detail here.
The Score
's time unit determines how the time
and duration
attributes of all its events are interpreted. You can convert a score between time units using the to()
method (e.g., score.to("second")
).
Conceptual Model
Think of a Score
as the root of a tree:
Score (e.g., ScoreTick)
│
├── ticks_per_quarter: int
│
├── Tracks (TrackList<TrackTick>)
│ ├── Track 1 (TrackTick)
│ │ ├── notes: NoteList<NoteTick>
│ │ ├── controls: ControlChangeList<ControlChangeTick>
│ │ └── ... (pitch_bends, pedals, lyrics)
│ └── Track 2 (TrackTick)
│ └── ...
│
├── Tempos (TempoList<TempoTick>)
│ ├── Tempo Event 1
│ └── ...
│
├── Time Signatures (TimeSignatureList<TimeSignatureTick>)
│ └── ...
│
├── Key Signatures (KeySignatureList<KeySignatureTick>)
│ └── ...
│
└── Markers (TextMetaList<TextMetaTick>)
└── ...
Working with Scores (Conceptual Flow)
- Load/Create: Instantiate a
Score
by loading a file (Score("file.mid")
) or creating an empty one (Score(tpq=480)
). - Inspect: Examine tracks, global events, and metadata.
- Manipulate: Apply transformations (e.g.,
shift_pitch
,clip
,sort
) or modify event lists directly. - Convert (Optional): Change time units using
to()
if needed for analysis or synthesis. - Save/Use: Save back to a file (
dump_midi
) or use for further processing (e.g., synthesis, feature extraction).
This flow highlights the Score
as the central object managing the musical data throughout its lifecycle.