from musp import *
from math import pi, sin, cos
from random import random
import numpy as np

tonic_freq = PitchedSound.note_frequency("F#", 3)
tempo_dur = 2.6/7

datadir = os.path.expanduser("~/.mu-sp")

def aulib(sound_dir):
    return os.path.join(datadir, "audio", sound_dir)

def rhlib(rh_name):
    return os.path.join(datadir, "rhythm/an_egg_rh", rh_name + ".rh")

def loctrans(far, angle, mem=[0]):
    mem[0] += pi*2/200
    return Location((angle, mem[0]), far)

def halftones_for_scale_deg(degree):
    semitones = [0, 2, 3, 5, 7, 8, 10][int(degree) - 1]
    if degree % 1 == .5:
        semitones += 1 
    return semitones

def deg_freq(degree):
    octave_mult = 1
    while degree > 7:
        degree -= 7
        octave_mult *= 2
    return tonic_freq*octave_mult * PitchedSound.temper_ratio**halftones_for_scale_deg(degree)

def fundamental_rhythm(beat):
    return beat.split([3, 3, 7, 3])

def apply_rhythm(beat, rhythm_file, key_sound_map):
    with open(rhythm_file) as rf:
        char_times = eval(''.join(rf.readline()))
    beat_map = beat.interleave_split(char_times)
    for key, beats in beat_map.iteritems():
        for beat in beats:
            try:
                for sound, loc in key_sound_map[key]:
                    beat.attach(sound, loc)
            except:
                beat.attach(*key_sound_map[key])

crystal_sound = RandomPitchedSound()
crystal_sound.populate_with_dir(aulib("crystal_ding"))

def add_tracks_fromto(tracklist, listoftracks):
    for track in tracklist:
        listoftracks.append(track)

def crystal_sounding(beat):
    beat.set_duration(tempo_dur*7)
    part1 = "565765243"
    crys1 = Track("crystals...", Sound.default_rate, padding=.5, end_padding=2)
    crys1_root = crys1.link_root(beat)
    with open(rhlib("crys_1_j")) as rf:
        char_times = eval(''.join(rf.readline()))
    beats = crys1_root.interleave_split(char_times)['j']
    
    for b, deg in zip(beats, part1):
        b.attach(SpreadSound(crystal_sound.for_pitch(4*deg_freq(int(deg))), (.1, .1, .1), .02, 3), loctrans(4, pi/2))

    return [crys1]

def crystal_rise(beat):
    beat.set_duration(tempo_dur*7)
    part2 = "34567"
    crys2 = Track("more crystals...", Sound.default_rate, padding=.5, end_padding=2)
    crys2_root = crys2.link_root(beat)
    beats = crys2_root.split_even(14)[9:]
    
    for b, deg in zip(beats, part2):
        b.attach(crystal_sound.for_pitch(2*deg_freq(int(deg))), loctrans(4, -pi/2))

    return [crys2]

def crystal_complex(beat):
    beat.set_duration(tempo_dur*14)
    #part3 = "78765774554"*2
    part3 = "17876577547187657232"
    crys3 = Track("more (muy complicated) crystals...", Sound.default_rate, padding=.5, end_padding=2)
    crys3_root = crys3.link_root(beat)
    beats = crys3_root.split([1, .5, .5, 1, 1, 1, 2, #groups of 7
                              2, 1, 2, 2,
                              2, 2, 1, 1, 1,
                              3, 1, 1, 2])
    
    for b, deg in zip(beats, part3):
        deg = int(deg) + 8
        b.attach(crystal_sound.for_pitch(deg_freq(int(deg)+4)), loctrans(4, -pi/6))

    return [crys3]