Source code for vis.analyzers.indexers.noterest

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#--------------------------------------------------------------------------------------------------
# Program Name:           vis
# Program Description:    Helps analyze music with computers.
#
# Filename:               controllers/indexers/noterest.py
# Purpose:                Index note and rest objects.
#
# Copyright (C) 2013 Christopher Antila
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#--------------------------------------------------------------------------------------------------
"""
.. codeauthor:: Christopher Antila <christopher@antila.ca>

Index note and rest objects.
"""

from music21 import stream, note
from vis.analyzers import indexer

[docs]def indexer_func(obj): """ Used internally by :class:`NoteRestIndexer`. Convert :class:`~music21.note.Note` and :class:`~music21.note.Rest` objects into a ``unicode`` string. :param obj: An iterable (nominally a :class:`~pandas.Series`) with an object to convert. Only the first object in the iterable is processed. :type obj: iterable of :class:`music21.note.Note` or :class:`music21.note.Rest` :returns: If the first object in the list is a :class:`music21.note.Rest`, the string ``u'Rest'``; otherwise the :attr:`~music21.note.Note.nameWithOctave` attribute, which is the pitch class and octave of the :class:`Note`. :rtype: unicode **Examples:** >>> from music21 import note >>> indexer_func([note.Note('C4')]) u'C4' >>> indexer_func([note.Rest()]) u'Rest' """ return u'Rest' if isinstance(obj[0], note.Rest) else unicode(obj[0].nameWithOctave)
[docs]class NoteRestIndexer(indexer.Indexer): """ Index :class:`~music21.note.Note` and :class:`~music21.note.Rest` objects in a :class:`~music21.stream.Part`. :class:`Rest` objects become ``'Rest'``, and :class:`Note objects become the unicode-format version of their :attr:`~music21.note.Note.nameWithOctave` attribute. """ required_score_type = 'stream.Part' def __init__(self, score, settings=None): """ :param score: A list of all the Parts to index. :type score: list of :class:`music21.stream.Part` :param settings: This indexer uses no settings, so this is ignored. :type settings: NoneType :raises: :exc:`RuntimeError` if ``score`` is not a list of the right type. """ super(NoteRestIndexer, self).__init__(score, None) self._types = [note.Note, note.Rest] self._indexer_func = indexer_func
[docs] def run(self): """ Make a new index of the piece. :returns: A :class:`DataFrame` of the new indices. The columns have a :class:`MultiIndex`; refer to the example below for more details. :rtype: :class:`pandas.DataFrame` **Example:** >>> the_score = music21.converter.parse('sibelius_5-i.mei') >>> the_score.parts[5] (the first clarinet Part) >>> the_notes = NoteRestIndexer(the_score).run() >>> the_notes['noterest.NoteRestIndexer']['5'] (the first clarinet Series) """ combinations = [[x] for x in xrange(len(self._score))] # calculate each voice separately results = self._do_multiprocessing(combinations) return self.make_return([unicode(x)[1:-1] for x in combinations], results)