#!/usr/bin/python ##### modules needed: from sys import * from Tkinter import * from time import * from random import * from math import sin import string ####### my modules: from midi_functions import * from scales import * ###### midi setup: if len(argv)<2: print "Usage: \n pymidichaos \n" exit() device_arg=str(argv[1]) open_port(device_arg) ###### init some variables: virgin=1 which=1 autocounter=0 new_note=60 old_low_note=60 old_high_note=60 ##### init some GUI-related variables: root=Tk() root.title("pymidichaos") runstate="START" tempo=IntVar(root) tempo.set(120) chaos=DoubleVar(root) chaos.set(11) note_range=IntVar(root) note_range.set(5) center=IntVar(root) center.set(20) split_point=IntVar(root) split_point.set(20) scale_string=StringVar(root) scale_string.set("modal") ####### scales: pentatonic_scale=create_scale(24,90,pentatonic) modal_scale=create_scale(24,90,modal) gypsy_scale=create_scale(24,90,gypsy) octatonic_scale=create_scale(24,90,octatonic) chromatic_scale=create_scale(24,90,chromatic) whole_tone_scale=create_scale(24,90,whole_tone) overtone_scale=create_scale(24,90,overtone) scale_choice=eval("%s_scale" % scale_string.get()) scale_size=len(scale_choice)-1 index=22 ##### evoked on start/stop button def reverse(): global runstate, old_note, which if runstate=="START": runstate="STOP!" buttons.RUN.config(text=runstate) main() else: runstate="START" which=1 buttons.RUN.config(text=runstate) note_off(0, old_low_note) note_off(1, old_high_note) ####### to config sliders after scale choice: def slider_config(): global scale_choice, scale_string, scale_size scale_choice=eval("%s_scale" % scale_string.get()) scale_size=len(scale_choice)-1 ###### Frames: menu=Menu(root) buttons=Frame(root) buttons.pack(side=BOTTOM, pady=4) sliders=Frame(root) sliders.pack(side=TOP, padx=5) ######### Widgets: scale_menu=Menu(menu) menu.add_cascade(label="Scales", menu=scale_menu) for scale in ["modal","pentatonic", "octatonic", "whole_tone", "gypsy", "chromatic", "overtone", "tabla"]: exec("""scale_menu.add_radiobutton(label=\"%s\", variable=scale_string, value=\"%s\", command=slider_config)""" % (scale,scale)) root.config(menu=menu) buttons.RUN = Button(buttons, text=runstate, command=reverse) buttons.QUIT = Button(buttons, text='QUIT', foreground='red', command=root.quit) sliders.chaos=Scale(sliders, from_=2, to=6.3, orient=HORIZONTAL, resolution=0.001, length=250, width=16, variable=chaos, label="chaos", showvalue=1) sliders.note_range=Scale(sliders, from_=1, to=24, orient=HORIZONTAL, length=250, width=16, variable=note_range, label="note_range", showvalue=1) sliders.center=Scale(sliders, from_=1, to=36, orient=HORIZONTAL, length=250, width=16, variable=center, label="center", showvalue=1) sliders.split_point=Scale(sliders, from_=24, to=90, orient=HORIZONTAL, length=250, width=16, variable=split_point, label="split point", showvalue=1) sliders.tempo=Scale(sliders, from_=30, to=220, orient=HORIZONTAL, length=250, width=16, variable=tempo, label="tempo", showvalue=1) ####### Packing: buttons.RUN.pack(side=LEFT, padx=8) buttons.QUIT.pack(side=LEFT, padx=8) sliders.chaos.pack(side=TOP, pady=2) sliders.note_range.pack(side=TOP, pady=2) sliders.center.pack(side=TOP, pady=2) sliders.split_point.pack(side=TOP, pady=2) sliders.tempo.pack(side=TOP, pady=2) ##################################################################### angle=1 place='below' boundary=split_point.get() def main(): global runstate,new_note,old_low_note,old_high_note,place,virgin,chaos,angle,scale_size,index,\ scale_choice,note_range, boundary, \ center, split_point while runstate=="STOP!": ############ get new note; answer=abs(sin(chaos.get()*angle)) index=bounce(int(round((note_range.get()*answer)))+center.get(),scale_size) new_note=scale_choice[index] ############## send data; if boundary!=split_point.get(): note_off(0, old_low_note) note_off(1, old_high_note) boundary=split_point.get() if new_note