forked from david-abel/felix
-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.py
168 lines (151 loc) · 5.77 KB
/
main.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
# Elliot Mitchell and Dave Abel | Carleton College | main.py |
# Main function calls for Felix.
import random
from MidiFile import MIDIFile
import os
from song import Song
from vector import Vector
from measure import Measure
from note import Note
# Global variables
root = 60
num_measures = 6
mode = 1
title = "test"
def queryUser():
global root
global num_measures
global mode
global title
root = raw_input("Please select a root node for your song (number from 40-80. 60 is Middle C) ")
while root.isdigit() != True or int(root) < 40 or int(root) > 80:
print "Invalid Selection."
root = raw_input("Choose an integer (number from 40-80. 60 is Middle C) ")
root = int(root)
num_measures = raw_input("How many measures do you want your song to be? ")
while num_measures.isdigit() != True or int(num_measures) > 100 and int(num_measures) < 0:
print "Invalid Selection."
num_measures = int(raw_input("Please select a reasonable number of measures (positive integer less than 100) "))
num_measures = int(num_measures)
print
print "|-----------------|-----|"
print "| Mode | Num |"
print "|-----------------|-----|"
print "| | |"
print "| Ionian (Major) | 1 |"
print "| Dorian | 2 |"
print "| Phrygian | 3 |"
print "| Lydian | 4 |"
print "| Mixolydian | 5 |"
print "| Aeolian (Minor) | 6 |"
print "| Locrian | 7 |"
print "| | |"
print "|_________________|_____|"
print
mode = raw_input("Choose a mode for your song: ")
# Make sure they entered a valid response
while mode.isdigit() != True or int(mode) < 0 or int(mode) > 7:
print "Invalid Selection."
mode = raw_input("Choose a scale (Please select a number from 1-7): ")
mode = int(mode)
title = raw_input("What do you want your song to be called? ")
def listen():
print
print "---Listening---"
print
queryUser()
master = Vector("master")
s = Song(root,mode,title)
# Build and play a song based on the master vector
for i in range(num_measures):
s.addMeasure(master)
print
print "This is the best song I know how to play!\n"
s.playSong()
raw_input("Press any key to return to the main menu: ")
def train():
print
print "---Training---"
print
queryUser()
my_vector = Vector()
s = Song(root,mode,title)
for i in range(num_measures):
# Generate a vector and build a measure from it.
training_vector = Vector("user")
s.addMeasure(training_vector)
s.playMeasure(title,i)
# Get feedback
user_opinion = raw_input("What did you think of that measure? (scale from 0-10): ")
while user_opinion.isdigit() == False or int(user_opinion) < 0 or int(user_opinion) > 10:
print "Invalid Response (please select a number from 0-10)"
user_opinion = raw_input("What did you think of that measure? (scale from 0-10): ")
user_opinion = int(user_opinion)
training_vector = s.measures[i].getVector() # update in the case that we repeated
my_vector.update(training_vector,.2,user_opinion)
# Get opinion on whole song
print "Here is your song!\n"
s.playSong()
song_opinion = int(raw_input("How much did you like that song? (scale from 0-10): "))
while song_opinion < 0 or song_opinion > 10:
print "Please enter an integer between 0 and 10: "
song_opinion = raw_input("How much did you like that song? (scale from 0-10): ")
while song_opinion.isdigit() != False or int(song_opinion) < 0 or int(song_opinion) > 10:
print "Invalid Response (please select a number from 0-10)"
song_opinion = raw_input("How much did you like that song? (scale from 0-10): ")
song_opinion = int(song_opinion)
# Update master based on user opinion
master = Vector("master")
master.update(my_vector,.05,song_opinion)
master.normalize()
master.writeToFile(".master.vct")
if user_opinion > 6 and num_measures > 7:
my_vector.writeToFile(".user_vectors.vct")
def help():
print
print
print
print "Felix is an Intelligent music maker! If you would like to help Felix become better at making music, you can (T)rain it by offering your opinion on some measures (and ultimately, a song consisting of those measures) that Felix will create. Felix learns by reducing music into a series of properties, which are then used to inform its decision on how to construct each measure. If you like the measure, then Felix says, 'Hey! Those were some nice properties!', and remembers them. It's ultimately a bit more complicated then that, but thats the jist of it. If you would prefer, you can (L)isten to Felix's best representation of 'good' music (based on learning from past users). Felix will create an entire song for you; just sit back and enjoy!."
print
print "Created by Dave Abel and Elliot Mitchell at Carleton College"
print
print
raw_input("Press any key to return to the main menu: ")
main()
def printMenu():
print
print "|--------|-----|"
print "| Action | Key |"
print "|--------|---- |"
print "| | |"
print "| Train | (T) |"
print "| Listen | (L) |"
print "| Help | (H) |"
print "| Quit | (Q) |"
print "| | |"
print "|________|_____|"
print
def main():
selection = raw_input("What would you like to do? ->")
if selection == "l" or selection == "L" or selection == "listen" or selection == "Listen":
listen()
printMenu()
elif selection == "t" or selection == "T" or selection == "train" or selection == "Train":
train()
printMenu()
elif selection == "q" or selection == "Q" or selection == "quit" or selection == "Quit":
quit()
elif selection == "h" or selection == "H" or selection == "help" or selection == "Help":
help()
printMenu()
else:
print
print "That was not a valid selection. Enter T to train, L to listen, H for help, or Q to quit. "
print
main() # Repeats!
if __name__ == "__main__":
printMenu()
print
print "Welcome to Felix, the intelligent music maker!"
print
main()