Source code for birdears.prequestion

"""This module implements pre-questions' progressions.

Pre questions are chord progressions or notes played before the question is
played, so to affirmate the sound of the question's key.

For example a common cadence is chords I-IV-V-I from the diatonic scale, which
in a key of `C` is `CM-FM-GM-CM` and in a key of `A` is `AM-DM-EM-AM`.

Pre-question methods should be decorated with `register_prequestion_method`
decorator, so that they will be registered as a valid pre-question method.
"""

from .sequence import Sequence

from functools import wraps

PREQUESTION_METHODS = {}
# http://stackoverflow.com/questions/5910703/howto-get-all-methods-of-a-pyt\
# hon-class-with-given-decorator
# http://stackoverflow.com/questions/5707589/calling-functions-by-array-ind\
# ex-in-python/5707605#5707605


[docs]def register_prequestion_method(f, *args, **kwargs): """Decorator for prequestion method functions. Functions decorated with this decorator will be registered in the `PREQUESTION_METHODS` global dict. """ @wraps(f) def decorator(*args, **kwargs): return f(*args, **kwargs) PREQUESTION_METHODS.update({f.__name__: f}) return decorator
[docs]class PreQuestion: def __init__(self, method, question): """This class implements methods for different types of pre-question progressions. Args: method (str): The method used in the pre question. question (obj): Question object from which to generate the pre-question sequence. """ self.METHOD = PREQUESTION_METHODS[method] self.question = question def __call__(self, *args, **kwargs): """Calls the resolution method and pass arguments to it. Returns a `birdears.Sequence` object with the pre-question generated by the method. """ return self.METHOD(question=self.question, *args, **kwargs)
[docs]@register_prequestion_method def none(question, *args, **kwargs): """Pre-question method that return an empty sequence with no delay. Args: question (obj): Question object from which to generate the pre-question sequence. (this is provided by the `Resolution` class when it is `__call__`ed) """ return Sequence(elements=[], duration=0, delay=0, pos_delay=0)
[docs]@register_prequestion_method def tonic_only(question, *args, **kwargs): """Pre-question method that only play's the question tonic note before the question. Args: question (object): Question object from which to generate the pre-question sequence. (this is provided by the `Resolution` class when it is `__call__`ed) """ tonic_pitch = question.tonic_pitch duration = question.durations['preq']['duration'] delay = question.durations['preq']['delay'] pos_delay = question.durations['preq']['pos_delay'] sequence = Sequence(elements=[tonic_pitch], duration=duration, delay=delay, pos_delay=pos_delay) return sequence
[docs]@register_prequestion_method def progression_i_iv_v_i(question, *args, **kwargs): """Pre-question method that play's a chord progression with triad chords built on the grades I, IV, V the I of the question key. Args: question (obj): Question object from which to generate the pre-question sequence. (this is provided by the `Resolution` class when it is `__call__`ed) """ # tonic_pitch = question.tonic_pitch # is_scale_descending = question tonic_index = 0 if not question.scale.is_descending else -1 tonic_pitch = question.scale[tonic_index] mode = question.mode duration = question.durations['preq']['duration'] delay = question.durations['preq']['delay'] pos_delay = question.durations['preq']['pos_delay'] degrees = [1, 4, 5, 1] sequence = Sequence(duration=duration, delay=delay, pos_delay=pos_delay) sequence.make_chord_progression(tonic_pitch=tonic_pitch, mode=mode, degrees=degrees) return sequence