示例#1
0
def generate_chord(key):
    """Returns a chord (list of notes)."""

    if keys.is_major_key(key):
        kp_data = probdata.KP_MAJOR_KEY_PROFILE_DATA
    else:
        kp_data = probdata.KP_MINOR_KEY_PROFILE_DATA

    result = []
    for scale_degree in range(12):
        x = random.uniform(0.0, 1.0)
        if x < kp_data[scale_degree]:
            result.append(scale_degree)

    return [60 + (key[0] + scale_degree) % 12 for scale_degree in result]
示例#2
0
def generate_note(previous_note, central_note, key):
    """Returns a note value generated from range, key, and proximity profiles.

    `previous_note` is the note value of the note that the generated note
    will follow.

    `central_note` is the mean note value of the musical piece we are
    generating a note for.

    `key` is a (tonic, is_major) tuple where `tonic` is the base note of the
    key, and `is_major` is 1 if the key is a major key and 0 otherwise.
    """

    # Select the major or minor key profile based on the key.
    if keys.is_major_key(key):
        key_profile_data = probdata.ESSEN_MAJOR_KEY_PROFILE_DATA
    else:
        key_profile_data = probdata.ESSEN_MINOR_KEY_PROFILE_DATA

    kp = probabilities.build_key_profile(key_profile_data, key)

    # Get the range and proximity profiles from `probdata`.
    rp_data = probdata.RANGE_PROFILE_DATA
    rp = probabilities.build_distance_profile(rp_data, central_note)
    pp_data = probdata.PROXIMITY_PROFILE_DATA
    pp = probabilities.build_distance_profile(pp_data, previous_note)

    # Generate a list of all notes to consider.
    notes = range(settings.MAX_NOTE + 1)

    # Calculate the probability of each possible next note.
    # The resulting table is indexed by note value.
    weights = [rp(i) * pp(i) * kp(i) for i in notes]

    # Select a note randomly in proportion to its weight.
    result_note = None
    x = random.uniform(0.0, sum(weights))

    for note, weight in enumerate(weights):
        if x < weight:
            result_note = note
            break
        else:
            x = x - weight

    return result_note