A fast, portable and lightweight library for engraving Music Encoding Initiative (MEI) music scores into SVG
This document covers querying element attributes, timing information, MIDI values, page locations, and other data from loaded music notation documents.
Access attributes of specific elements in the loaded document.
class toolkit:
def getElementAttr(self, xmlId: str) -> dict:
"""
Get all attributes of an element as a dictionary.
Returns all attributes, including those not directly supported
by Verovio.
Args:
xmlId: The @xml:id of the element
Returns:
Dictionary with all element attributes
"""
def getNotatedIdForElement(self, xmlId: str) -> str:
"""
Get the ID of the notated (original) element.
When elements are expanded (e.g., due to repeats), this returns
the ID of the original notated element.
Args:
xmlId: The @xml:id of an element (notated or expanded)
Returns:
ID string of the notated element
"""
def getExpansionIdsForElement(self, xmlId: str) -> list:
"""
Get IDs of all elements (notated and expanded) for a given element.
When notation includes repeats or other expansions, this returns
the IDs of both the notated element and all its expanded instances.
Args:
xmlId: The @xml:id of an element
Returns:
List containing all related IDs
"""Find which page contains a specific element.
class toolkit:
def getPageWithElement(self, xmlId: str) -> int:
"""
Get the page number where an element is rendered.
Takes into account current layout options.
Args:
xmlId: The @xml:id of the element
Returns:
Page number (1-based) where element appears, or 0 if not found
"""Query temporal information for elements.
class toolkit:
def getElementsAtTime(self, millisec: int) -> dict:
"""
Get IDs of elements being played at a specific time.
Args:
millisec: Time in milliseconds
Returns:
Dictionary with page number and list of note IDs being played
"""
def getTimeForElement(self, xmlId: str) -> int:
"""
Get the playback time for an element.
renderToMIDI() must be called before using this method.
Args:
xmlId: The @xml:id of the element
Returns:
Time in milliseconds when element is played
"""
def getTimesForElement(self, xmlId: str) -> dict:
"""
Get detailed timing information for a note element.
Returns score time and real time values for onset, offset,
and tied duration.
Args:
xmlId: The @xml:id of a note element
Returns:
Dictionary with timing information:
- scoreTimeOnset: Score time onset
- scoreTimeOffset: Score time offset
- scoreTimeTiedDuration: Score time tied duration
- realTimeOnsetMilliseconds: Real time onset in ms
- realTimeOffsetMilliseconds: Real time offset in ms
- realTimeTiedDurationMilliseconds: Real time tied duration in ms
"""Access MIDI values for musical elements.
class toolkit:
def getMIDIValuesForElement(self, xmlId: str) -> dict:
"""
Get MIDI values for an element.
renderToMIDI() must be called before using this method.
Args:
xmlId: The @xml:id of the element
Returns:
Dictionary with MIDI values (pitch, velocity, channel, etc.)
"""Extract features for music information retrieval tasks.
class toolkit:
def getDescriptiveFeatures(self, options: dict | None = None) -> dict:
"""
Extract descriptive features from the loaded document.
Features are tailored for implementing incipit search and
other music information retrieval tasks.
Args:
options: Dictionary with feature extraction options, optional
Returns:
Dictionary with requested features
"""import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
# Find which page contains a specific note
note_id = "note-123"
page_num = tk.getPageWithElement(note_id)
if page_num > 0:
print(f"Note {note_id} is on page {page_num}")
# Render that page
svg = tk.renderToSVG(pageNo=page_num)
else:
print(f"Note {note_id} not found")import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
# Get all attributes of an element
element_id = "note-456"
attributes = tk.getElementAttr(element_id)
print(f"Attributes of {element_id}:")
for attr_name, attr_value in attributes.items():
print(f" {attr_name}: {attr_value}")
# Check specific attributes
if 'pname' in attributes:
print(f"Pitch name: {attributes['pname']}")
if 'oct' in attributes:
print(f"Octave: {attributes['oct']}")import verovio
import time
tk = verovio.toolkit()
tk.loadFile("score.mei")
# Render to MIDI first (required for timing queries)
tk.renderToMIDI()
# Simulate playback - highlight notes at current time
playback_time_ms = 0
duration_ms = 10000 # 10 seconds
while playback_time_ms < duration_ms:
# Get elements being played at current time
elements = tk.getElementsAtTime(playback_time_ms)
if elements.get('notes'):
page = elements.get('page')
note_ids = elements.get('notes')
print(f"Time {playback_time_ms}ms: Page {page}, Notes: {note_ids}")
time.sleep(0.1)
playback_time_ms += 100import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
tk.renderToMIDI()
# Analyze timing for a note
note_id = "note-789"
times = tk.getTimesForElement(note_id)
print(f"Timing for {note_id}:")
print(f" Score time onset: {times['scoreTimeOnset']}")
print(f" Score time offset: {times['scoreTimeOffset']}")
print(f" Real onset: {times['realTimeOnsetMilliseconds']} ms")
print(f" Real offset: {times['realTimeOffsetMilliseconds']} ms")
print(f" Duration: {times['realTimeTiedDurationMilliseconds']} ms")
# Calculate duration
duration = times['realTimeOffsetMilliseconds'] - times['realTimeOnsetMilliseconds']
print(f" Calculated duration: {duration} ms")import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
tk.renderToMIDI()
# Get MIDI values for analysis
note_id = "note-101"
midi_values = tk.getMIDIValuesForElement(note_id)
print(f"MIDI values for {note_id}:")
if 'pitch' in midi_values:
print(f" MIDI pitch: {midi_values['pitch']}")
if 'velocity' in midi_values:
print(f" Velocity: {midi_values['velocity']}")
if 'channel' in midi_values:
print(f" Channel: {midi_values['channel']}")import verovio
tk = verovio.toolkit()
tk.loadFile("score_with_repeats.mei")
# Get the notated (original) ID for an expanded element
expanded_id = "note-repeat-2-note-123"
notated_id = tk.getNotatedIdForElement(expanded_id)
print(f"Notated ID: {notated_id}")
# Get all expansion IDs for a notated element
expansion_ids = tk.getExpansionIdsForElement(notated_id)
print(f"All expansions: {expansion_ids}")
# Query attributes of the notated element
notated_attrs = tk.getElementAttr(notated_id)
print(f"Notated element attributes: {notated_attrs}")import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
# Extract features for incipit search
features = tk.getDescriptiveFeatures()
print("Extracted features:")
for feature_name, feature_value in features.items():
print(f" {feature_name}: {feature_value}")
# Use features for music similarity comparison
# or incipit-based searchimport verovio
class ScoreViewer:
def __init__(self, filename):
self.tk = verovio.toolkit()
self.tk.loadFile(filename)
self.tk.renderToMIDI() # Enable timing queries
def get_element_info(self, element_id):
"""Get comprehensive information about an element."""
info = {
'attributes': self.tk.getElementAttr(element_id),
'page': self.tk.getPageWithElement(element_id),
'times': self.tk.getTimesForElement(element_id),
'midi': self.tk.getMIDIValuesForElement(element_id)
}
return info
def highlight_elements_at_time(self, millisec):
"""Get elements to highlight during playback."""
return self.tk.getElementsAtTime(millisec)
def find_notated_element(self, expanded_id):
"""Find the original notated element for an expanded one."""
return self.tk.getNotatedIdForElement(expanded_id)
# Usage
viewer = ScoreViewer("score.mei")
note_info = viewer.get_element_info("note-123")
print(f"Note is on page {note_info['page']}")
print(f"Note attributes: {note_info['attributes']}")import verovio
tk = verovio.toolkit()
tk.loadFile("score.mei")
tk.renderToMIDI()
# Find all elements played in a time range
start_time = 1000 # 1 second
end_time = 3000 # 3 seconds
interval = 100 # 100ms steps
elements_in_range = []
for t in range(start_time, end_time, interval):
result = tk.getElementsAtTime(t)
if result.get('notes'):
elements_in_range.extend(result['notes'])
# Remove duplicates
unique_elements = list(set(elements_in_range))
print(f"Elements played between {start_time}-{end_time}ms:")
print(unique_elements)
# Get details for each element
for elem_id in unique_elements:
attrs = tk.getElementAttr(elem_id)
print(f" {elem_id}: {attrs}")Install with Tessl CLI
npx tessl i tessl/pypi-verovio