class DragFilter(Filter): def init(self): self.osc = Oscillator(freq=1) self.osc2 = Oscillator(freq=5, zero=True, phase=20) self.amplitude = 0 self.add_parameter(name="amplitude", min=10, max=60) def compute(self, frame): f = cv.cvtColor(cv.medianBlur(frame, 3), cv.COLOR_BGR2GRAY) mask = cv.adaptiveThreshold(f, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 17, 4) invert_mask = 255 - mask source = cv.bitwise_and(frame, frame, mask=invert_mask) lfo = self.osc2.next() self.osc.freq = lfo * 5 o = self.osc.next() # print(self.amplitude) self.M = np.float32([[1, 0, self.amplitude], [0, 1, self.amplitude]]) acc = cv.addWeighted( self._previous, 0.9, cv.warpAffine(source, self.M, (self.cols, self.rows)), 1, 0.0, ) self._previous = acc # invert_frame = cv.bitwise_not(frame) # acc = cv.bitwise_or(acc, cv.bitwise_and(invert_frame, invert_frame, mask=invert_mask)) return acc
def __init__(self): # config app_title = "Oscbar" interval = 2 # seconds per calibration step # initial oscillator settings self.wave_type = "sine_wave" self.amplitude = 0.5 self.frequency = 440 self.store_wave = None self.store_freq = None # object instances self.app = rumps.App(app_title, icon=APP_ICON) self.oct_timer = rumps.Timer( lambda sender, factor=2, max_freq=880, title='Octave Walk': self. advance_frequency(sender, factor, max_freq, title), interval) self.oct_thirds_timer = rumps.Timer( lambda sender, factor=(2**(1 / 3)), max_freq=880, title ='Octave Walk â…“': self.advance_frequency( sender, factor, max_freq, title), interval) self.osc = Oscillator(self.wave_type, self.amplitude, self.frequency) # set up menu self.build_menu() self.osc_ready_menu()
def main( ramp_start=START, ramp_end=START + RISE, ramp_seconds=RISE * 60, feel=90, osc_multiplier=3, active_seceonds=2, inactive_seconds_min=2, inactive_seconds_max=10, ): ramp = Ramp(ramp_start, ramp_end, ramp_seconds) seq = Sequence() time_osc = Oscillator(inactive_seconds_min, inactive_seconds_max, 120) with commander() as cmd: cmd.set_power('H') cmd.set_mode(Mode.CONTINUOUS) cmd.set_feel(feel) while True: base_level = ramp.get_value() + osc_multiplier * seq.get_value() cmd.set_level('A', base_level) sleep(active_seceonds) cmd.set_level('A', 0) # inactive_seconds = randint(inactive_seconds_min, inactive_seconds_max) inactive_seconds = time_osc.get_value() sleep(inactive_seconds)
def plot_theta_vs_theta_dash(): pendulum = Oscillator(alpha=0.8, radius=1) time_steps = 400 time_max = 10.0 plt.axes(xlim=(-0.1, 0.1), ylim=(-0.25, 0.25)) trajectory = pendulum.get_trajectory(time_max, time_steps) theta = [position for position, velocity in trajectory] theta_dash = [velocity for position, velocity in trajectory] plt.plot(theta, theta_dash, "b")
def plot_underdamped_pendulum(): pendulum = Oscillator(alpha=0.8, radius=1) time_steps = 400 time_max = 10.0 time = numpy.linspace(0, time_max, time_steps + 1) plt.axes(xlim=(0, 10), ylim=(-0.2, 0.2)) trajectory = pendulum.get_trajectory(time_max, time_steps) theta = [position for position, velocity in trajectory] plt.plot(time, theta, "r")
def initAudio(self): """ Inits the two oscillators and their channels. """ #guide tone self.guide_osc = Oscillator('sine', self.guide, BUFFER_SIZE) self.guide_ch = pygame.mixer.Channel(0) self.guide_ch.set_volume(0.9/2.0) #adjustable (the knob one), starts at same freq self.osc = Oscillator('sine', self.pitch, BUFFER_SIZE) self.osc_ch = pygame.mixer.Channel(1) self.osc_ch.set_volume(0.9/2.0)
def initAudio(self): """ Inits the two oscillators and their channels. """ #guide tone self.guide_osc = Oscillator('sine', self.guide, BUFFER_SIZE) self.guide_ch = pygame.mixer.Channel(0) self.guide_ch.set_volume(0.9 / 2.0) #adjustable (the knob one), starts at same freq self.osc = Oscillator('sine', self.pitch, BUFFER_SIZE) self.osc_ch = pygame.mixer.Channel(1) self.osc_ch.set_volume(0.9 / 2.0)
def __init__(self, no_of_voices=2, no_of_bass_voices=1, waveform="sine", samplerate=None, transposition_factor=1.0, attack_time=0.01, decay_time=0.01, after_decay_level=1.0, release_time=1.0, bass_attack_time=0.01, bass_decay_time=0.01, bass_after_decay_level=1.0, bass_release_time=1.0, bass_transposition_factor=1.0, volume=0.3): self.no_of_voices = no_of_voices self.no_of_bass_voices = no_of_bass_voices self.current_voice_index = 0 self.current_bass_voice_index = 0 self.samplerate = samplerate self.oscillators = [Oscillator(waveform=waveform, \ dt=1.0/self.samplerate, frequency=100.0) \ for i in range(self.no_of_voices)] self.bass_oscillators = [Oscillator(waveform=waveform, \ dt=1.0/self.samplerate, frequency=100.0) \ for i in range(self.no_of_bass_voices)] self.transposition_factor = transposition_factor self.bass_transposition_factor = bass_transposition_factor self.envelopes = [envelope.Envelope(attack_time=attack_time, \ decay_time=decay_time, \ after_decay_level=after_decay_level, \ release_time=release_time, dt=1.0/self.samplerate) \ for i in range(self.no_of_voices)] self.bass_envelopes = [envelope.Envelope(attack_time=bass_attack_time, \ decay_time=bass_decay_time,\ after_decay_level=bass_after_decay_level,\ release_time=bass_release_time, dt=1.0/self.samplerate) \ for i in range(self.no_of_bass_voices)] self.start_envelope = False self.release_envelope = False self.start_bass_envelope = False self.release_bass_envelope = False self.is_recording = False self.recorded_wave = [] self.volume = volume
def to_pcm_audio(self): oscillator = Oscillator(self._frequency, self._phase) envelope = Envelope() for point in self._amplitude_envelope_points: envelope.add_point(point) samples = oscillator.get_output(self._sample_times) samples *= envelope.get_output(self._sample_times) if self._base_pcm_audio: samples += self._base_pcm_audio.samples return PcmAudio(self._reference_pcm_audio.sampling_rate, samples)
class Crawler(object): """ Attraction A class to describe a thing in our world, has vectors for position, velocity, and acceleration. Also includes scalar values for mass, maximum velocity, and elasticity. """ def __init__(self): self.acc = PVector() self.vel = PVector(random(-1, 1), random(-1, 1)) self.loc = PVector(random(width), random(height)) self.mass = random(8, 16) self.osc = Oscillator(self.mass*2) def applyForce(self, force): f = force.get() f.div(self.mass) self.acc.add(f) def update(self): # Method to update position self.vel.add(self.acc) self.loc.add(self.vel) # Multiplying by 0 sets the all the components to 0 self.acc.mult(0) self.osc.update(self.vel.mag()/10) def display(self): # Method to display angle = self.vel.heading2D() pushMatrix() translate(self.loc.x, self.loc.y) rotate(angle) ellipseMode(CENTER) stroke(0) fill(175, 100) ellipse(0, 0, self.mass*2, self.mass*2) self.osc.display(self.loc) popMatrix()
class Crawler(object): """ Attraction A class to describe a thing in our world, has vectors for position, velocity, and acceleration. Also includes scalar values for mass, maximum velocity, and elasticity. """ def __init__(self): self.acc = PVector() self.vel = PVector(random(-1, 1), random(-1, 1)) self.loc = PVector(random(width), random(height)) self.mass = random(8, 16) self.osc = Oscillator(self.mass * 2) def applyForce(self, force): f = force.get() f.div(self.mass) self.acc.add(f) def update(self): # Method to update position self.vel.add(self.acc) self.loc.add(self.vel) # Multiplying by 0 sets the all the components to 0 self.acc.mult(0) self.osc.update(self.vel.mag() / 10) def display(self): # Method to display angle = self.vel.heading2D() pushMatrix() translate(self.loc.x, self.loc.y) rotate(angle) ellipseMode(CENTER) stroke(0) fill(175, 100) ellipse(0, 0, self.mass * 2, self.mass * 2) self.osc.display(self.loc) popMatrix()
def main(): ndim = 2 np.random.seed(3) tf = 25 nsteps = 1000 u_init = [0, 0] noise = Noise([0, tf]) oscil = Oscillator(noise, tf, nsteps, u_init) my_map = BlackBox(map_def, args=(oscil, )) n_init = 4 n_iter = 80 mean, cov = np.zeros(ndim), np.ones(ndim) domain = [[-6, 6]] * ndim inputs = GaussianInputs(domain, mean, cov) X = inputs.draw_samples(n_init, "lhs") Y = my_map.evaluate(X) o = OptimalDesign(X, Y, my_map, inputs, fix_noise=True, noise_var=0.0, normalize_Y=True) m_list = o.optimize(n_iter, acquisition="US", num_restarts=10, parallel_restarts=True) # Compute true pdf filename = "map_samples{:d}D.txt".format(ndim) try: smpl = np.genfromtxt(filename) pts = smpl[:, 0:-1] yy = smpl[:, -1] except: pts = inputs.draw_samples(n_samples=100, sample_method="grd") yy = my_map.evaluate(pts, parallel=True, include_noise=False) np.savetxt(filename, np.column_stack((pts, yy))) pdf = custom_KDE(yy, weights=inputs.pdf(pts)) for ii in np.arange(0, n_iter + 1, 10): pb, pp, pm = model_pdf(m_list[ii], inputs, pts=pts) plot_pdf(pdf, pb, [pm, pp], filename="pdfs%.4d.pdf" % (ii), xticks=[-3, 0, 3], yticks=[-8, -3, 2]) plot_smp(m_list[ii], inputs, n_init, filename="smps%.4d.pdf" % (ii), xticks=[-6, 0, 6], yticks=[-5, 0, 5], cmapticks=[-2, -1, 0, 1, 2])
def main( ramp_start=START, ramp_end=START + RISE, ramp_seconds=RISE * 60, warn_adjustment=2, feel=80, warn_seconds=3, bang_adjustment_min=10, bang_adjustment_max=20, active_seconds=1, inactive_seconds_min=10, inactive_seconds_max=30, ): ramp = Ramp(ramp_start, ramp_end, ramp_seconds) seq = Sequence() time_osc = Oscillator(inactive_seconds_min, inactive_seconds_max, 120) bang_adjustment = bang_adjustment_min with commander() as cmd: cmd.set_mode(Mode.CONTINUOUS) cmd.set_power('H') cmd.set_feel(feel) while True: active_level = ramp.get_value() warn_level = active_level // warn_adjustment if randint(1, 6) == 1: # bang active_level += bang_adjustment bang_adjustment = min(bang_adjustment + 1, bang_adjustment_max) cmd.set_level('A', warn_level) sleep(warn_seconds) cmd.set_level('A', active_level) sleep(active_seconds) cmd.set_level('A', 0) # inactive_seconds = randint(inactive_seconds_min, inactive_seconds_max) inactive_seconds = time_osc.get_value() sleep(inactive_seconds)
def main(): dev = OpenClDevice() dev.build('oscillator.cl') length_sec = 3.0 n_instances = 256 # larger values cause mysterious behavior that smells like corrupted memory or instances modifying each other's memory local_size = 64 # must divide n_instances, and my video card prefers it to be at least 32 sample_freq = 44100.0 n_samples = int(length_sec * sample_freq) a = instruments.violin_envelope() vib = vibrato.generate(290, 3, 3, 6, 0.4, [3, 5, 4, 1], [1, 8, 4, 1]) partials = [] for i in range(len(a)): n = i + 1 # n=1 for fundamental p = Partial( vib, Pie.from_string("0 0,0.2 0.5 c ; , 2 1 ; , 3 0")) # gradual onset p = copy.deepcopy(p).scale_f(n).scale_a(a[i]) partials.append(p) # resp = lambda f:1.0 # no filtering # resp = lambda f:instruments.log_comb_response(f) resp = lambda f: instruments.fisher_response(f) for partial in partials: partial.filter(resp) osc = Oscillator( { 'n_samples': n_samples, 'n_instances': n_instances, 't0': 0.0, 'dt': 1 / sample_freq }, partials) if False: print("graphing...") #attack_envelope.graph("a.png",0,3,100) partials[10].a.graph("a.png", 0, 3, 100) print("...done") timer_start = time.perf_counter() osc.run(dev, local_size) timer_end = time.perf_counter() print("return code=", osc.error_code()) if osc.error_code() != 0: sys.exit(" ******* exiting with an error **********") print("wall-lock time for computation = ", (timer_end - timer_start) * 1000, "ms") write_file('a.wav', osc.y(), n_samples, sample_freq)
def main( ramp_start=START, ramp_end=START + RISE, ramp_seconds=RISE * 60, feel=80, speed=65, osc_max=10, osc_period_seconds=120, step_seconds=5, ): ramp = Ramp(ramp_start, ramp_end, ramp_seconds) osc = Oscillator(0, osc_max, osc_period_seconds) with commander() as cmd: cmd.set_mode(Mode.WATERFALL) cmd.set_power('H') cmd.set_speed(speed) cmd.set_feel(feel) while True: base_level = ramp.get_value() + osc.get_value() cmd.set_level('A', base_level) sleep(step_seconds)
def main( ramp_start=START, ramp_end=START + RISE, ramp_seconds=RISE * 60, warn_adjustment=10, feel=80, speed=90, warn_seconds=3, osc_multiplier=2, active_seconds=5, inactive_seconds_min=5, inactive_seconds_max=15, ): ramp = Ramp(ramp_start, ramp_end, ramp_seconds) seq = Sequence() time_osc = Oscillator(inactive_seconds_min, inactive_seconds_max, 120) with commander() as cmd: cmd.set_power('H') cmd.set_mode(Mode.PULSE) cmd.set_feel(feel) cmd.set_speed(speed) while True: base_level = ramp.get_value() + osc_multiplier * seq.get_value() warn_level = base_level - warn_adjustment cmd.set_level('A', warn_level) sleep(warn_seconds) cmd.set_level('A', base_level) sleep(active_seconds) cmd.set_level('A', 0) # inactive_seconds = randint(inactive_seconds_min, inactive_seconds_max) inactive_seconds = time_osc.get_value() sleep(inactive_seconds)
def scene(self): spaceships_guns = [(10, 0), (gol.nx_c - 46, gol.ny_c - 9)] for i in range(len(spaceships_guns)): spaceship_guns = SpaceshipGuns(spaceships_guns[i][0], spaceships_guns[i][1]) if (i % 2) == 1: spaceship_guns.rot90(2) gol.seed(spaceship_guns, spaceship_guns.pos_x, spaceship_guns.pos_y) oscillators = [(gol.nx_c - 27, 10), (10, gol.ny_c - 27)] for i in oscillators: oscilltor = Oscillator(i[0], i[1]) gol.seed(oscilltor, oscilltor.pos_x, oscilltor.pos_y) sticks = [(5, 10), (5, 20), (gol.nx_c - 6, gol.ny_c - 11), (gol.nx_c - 6, gol.ny_c - 21)] for i in sticks: stick = Stick(i[0], i[1]) gol.seed(stick, stick.pos_x, stick.pos_y) spaceships = [Spaceship(40, 80)] spaceships[0].rot90() gol.seed(spaceships[0], spaceships[0].pos_x, spaceships[0].pos_y)
def test_amplitude_decreases_when_friction_present(self): oscillator = Oscillator(alpha=1.0, radius=1.0) self.assertTrue( oscillator.state[0] > oscillator.get_trajectory(10.0, 500)[-1][0])
def __init__(self): self.acc = PVector() self.vel = PVector(random(-1, 1), random(-1, 1)) self.loc = PVector(random(width), random(height)) self.mass = random(8, 16) self.osc = Oscillator(self.mass*2)
spike_gen_in_dn_id = 2 ei_rate = 1 # probability of an excitatory synapse between any pair of excitatory and inhibitory neurons ie_rate = 1 # probability of an inhibitory synapse between any pair of excitatory and inhibitory neurons nids_exc = range(exc_offset, num_exc + exc_offset) nids_inh = range(inh_offset, num_inh + inh_offset) # init a network generator net_gen = n.NetworkGenerator() # create spikegens spikegen_input_up = Neuron(chip_id, core_id_exc, spike_gen_in_up_id, True) spikegen_input_dn = Neuron(chip_id, core_id_exc, spike_gen_in_dn_id, True) oscillator = Oscillator(net_gen, spikegen_input_up, spikegen_input_dn, exc_offset, inh_offset, osc_input_rate=120) nids_exc, nids_inh, spike_gen_osc_id = oscillator.get_ids() # print network net_gen.print_network() # make a dynapse1config using the network new_config = net_gen.make_dynapse1_configuration() # apply the configuration model.apply_configuration(new_config) # get the global neuron IDs of the neurons monitored_global_nids_exc = [ ut.get_global_id(chip_id, core_id_exc, nid_exc) for nid_exc in nids_exc
import math from matplotlib import animation from matplotlib import pyplot as plt from oscillator import Oscillator fig = plt.figure() ax = plt.axes(xlim=(-0.1, 0.1), ylim=(-0.2, 1)) pendulum_bob, = ax.plot([], [], lw=2, marker='o', color="r", markersize=30) pendulum_rod, = ax.plot([], [], lw=2, color="black") time_steps = 400 time_max = 10.0 pendulum = Oscillator() trajectory = pendulum.get_trajectory(time_max, time_steps) y = [position for position, velocity in trajectory] x_coord = [math.sin(position) for position, velocity in trajectory] y_coord = [(1 - math.cos(position)) for position, velocity in trajectory] def init(): pendulum_bob.set_data([], []) plt.title("Damped Pendulum Motion") plt.xlabel("X", fontsize=13, family='monospace') plt.ylabel("Y", fontsize=13, family='monospace') return pendulum_bob,
class Game: """ The main game class. This deals with two oscillators, of which one is adjustable. The diffrence between those frequencies are measured and compared to the wanted interval. Margin of errors is given i cents. """ screen = None center = None #screen center instructions = None #instructions surface interval = None #interval surface result = None # surface for result displaying path = None #for resources #GUI elements knob = None knob_rect = None plate = None running = False #state check intevals = None #interval array guide_osc = None # guide note oscillator guide = None # guide_osc frequency osc = None # user ajustable oscillator guide_ch = None #Audio channel osc_ch = None #Audio channel pitch = None # osc frequency steps = 1 # number of musical notes. Level one starts at an octave prev_steps = [] #stores old game settings max_freq = 0 # 4 x base oscillator frequency (two octaves) min_freq = 0 # bace oscillator frequency level = 1 #level pause = False # pausing main loop practise = False tuner = None acceptable_off = 10 # how many cents off for a corrects answer? def __init__(self, gradient, path): """ gradient: A gradient object to act as background path: path to images """ self.screen = gradient self.center = self.screen.get_rect().center self.path = path # interval class self.intervals = Interval() self.instr_str = 'UP AND DOWN ARROWS COARSE TUNE. USE LEFT AND RIGHT FOR FINE ADJUSTMENT' self.conf_str = 'PRESS ENTER TO CONFIRM' self.setLevel(self.level) self.initGUI() #self.initAudio() def initGUI(self): """ Inits the graphical components """ #clear background self.screen.clear() self.screen.draw() #knob image img = pygame.image.load(self.path + 'knob.png') #plates self.plate = pygame.image.load(self.path + 'rust.png') self.knob = Knob(img) self.knob.set_plate(self.plate) #self.knob.set_shadow((-6,-4), 150, 25) knb_center = self.knob.get_rect().center self.knob = (self.knob, (self.center[0]-knb_center[0], self.center[1]-knb_center[1])) # also stores knob.rect at blit time self.center = self.screen.get_rect().center #"back" back_img = pygame.image.load(self.path + 'back.png') back_pos = (30,30) #tuple width the image and it's position and a third element containting elements Rect. self.back = (back_img, (30,30), self.screen.blit(back_img, back_pos)) #arrow arrow_img = pygame.image.load(self.path + 'arrow.png') self.arrow = (arrow_img, (self.center[0] - arrow_img.get_width()/2, 104)) #instructions, texts instrs = ['UP', 'DOWN', 'FINE UP', 'FINE DOWN', 'PRESS ENTER TO CONFIRM'] font = pygame.font.Font(self.path + 'Actor-Regular.ttf', 10) #instructions, key images key_images = pygame.Surface((184, 69), pygame.SRCALPHA, 32) #collecting those images in a surface, for flexible positioning. key_images_cp = key_images.get_rect().center img = pygame.image.load(self.path + 'key.png') up = pygame.transform.rotozoom(img, 90, 1) key_images.blit(up, (key_images_cp[0] - up.get_size()[0]/2, 0)) #up arrow key_images.blit(font.render(instrs[0], True, BLACK), (key_images_cp[0] - font.size(instrs[0])[0]/2, 9)) #up text key_images.blit(font.render(instrs[3], True, BLACK), (0, key_images_cp[1] - font.size(instrs[3])[1]/2)) #left text left = pygame.transform.rotozoom(img, 180, 1) key_images.blit(left, (font.size(instrs[3])[0] + 5, key_images_cp[1] - left.get_size()[1]/2)) #left arrow right = img key_images.blit(right, (key_images.get_width() - font.size(instrs[3])[0] - 5 - right.get_size()[0], key_images_cp[1] - right.get_size()[1]/2)) #right arrow (reflects left) key_images.blit(font.render(instrs[2], True, BLACK), (key_images.get_width() - font.size(instrs[3])[0] + 5 - right.get_size()[0], key_images_cp[1] - font.size(instrs[2])[1]/2)) #right text key_images.blit(font.render(instrs[1], True, BLACK), (key_images_cp[0] - font.size(instrs[1])[0]/2, 44)) #down text down = pygame.transform.rotozoom(img, 270, 1) key_images.blit(down, (key_images_cp[0] - down.get_size()[0]/2, 69 - down.get_size()[1])) #up arrow #public parent container for instructions self.instructions = pygame.Surface((self.screen.get_width(), 115), pygame.SRCALPHA, 32) self.instructions.blit(key_images, (self.instructions.get_rect().center[0] - key_images_cp[0], 0)) self.instructions.blit(font.render(instrs[4], True, BLACK),(self.instructions.get_rect().center[0] - font.size(instrs[4])[0]/2, key_images.get_height() + 20)) def initAudio(self): """ Inits the two oscillators and their channels. """ #guide tone self.guide_osc = Oscillator('sine', self.guide, BUFFER_SIZE) self.guide_ch = pygame.mixer.Channel(0) self.guide_ch.set_volume(0.9/2.0) #adjustable (the knob one), starts at same freq self.osc = Oscillator('sine', self.pitch, BUFFER_SIZE) self.osc_ch = pygame.mixer.Channel(1) self.osc_ch.set_volume(0.9/2.0) def setLevel(self, level): """ inits different levels """ lowest_freq = 220 # low limit # for use in levels > 4 rand_guide = self.stepToFreq(random.randint(0, 12), 220) # 220Hz < 440Hz in perfect notes. if level == 1: self.guide = 440 self.steps = 0 self.pitch = self.stepToFreq(1, self.guide) elif level == 2: self.guide = 440 self.steps = 12 self.pitch = self.stepToFreq(11, self.guide) elif level == 3: self.guide = 440 self.steps = 7 self.pitch = self.stepToFreq(6, self.guide) elif level == 4: self.guide = rand_guide self.steps = 5 init_rand = random.randint(0, 11) self.pitch = self.stepToFreq(init_rand, self.guide) elif level == 5: self.guide = rand_guide self.steps = self.randExclude(self.prev_steps + [5], 0,12) init_rand = random.randint(0, 11) self.pitch = self.stepToFreq(11, self.guide) elif level == 6: self.guide = rand_guide self.steps = self.randExclude(self.prev_steps + [6]) init_rand = random.randint(0, 24) self.pitch = self.stepToFreq(11, self.guide) elif level >= 7: self.guide = rand_guide self.steps = random.randint(0,24) # whole range init_rand = random.randint(0, 24) self.pitch = self.stepToFreq(11, self.guide) else: return False self.prev_steps.append(self.steps) #store, for unique intervals the first 6 levels # set min/max frequencies self.max_freq = self.guide * 4 # maximum frequency self.min_freq = self.guide - 20# minimum frequency #set interval text self.setIntervalText() def setIntervalText(self): """ Text to display the wanted interval """ font = pygame.font.Font(pygame.font.get_default_font(), 18) img = font.render(self.intervals.at(self.steps), True, BLACK) #interval surface gets made every time function is called, this is done during pauses in main loop. The inefficiency should not be a problem. self.interval = pygame.Surface((self.screen.get_width(), font.get_height()), SRCALPHA, 32) self.interval.blit(img, (self.center[0] - img.get_width()/2, 0)) def draw(self): """ draw screen """ self.back = (self.back[0], self.back[1], self.screen.blit(self.back[0], self.back[1])) self.screen.blit(self.arrow[0], self.arrow[1]) self.screen.blit(self.knob[0], self.knob[1]) if not self.pause: self.screen.blit(self.interval, (0, 70)) self.screen.blit(self.instructions, (0, 285)) #practise mode? if self.practise is True: #display tuner goal = self.stepToFreq(self.steps, self.guide_osc.frequency()) cents = self.hertzToCents(goal, self.pitch) self.tuner.update(cents) self.screen.blit(self.tuner, (self.center[0]-self.tuner.center[0], 20)) self.screen.draw() def updateChannels(self): """ update audio queues """ if self.guide_ch.get_queue() == None: self.guide_ch.queue(self.guide_osc.samples()) if self.osc_ch.get_queue() == None: self.osc_ch.queue(self.osc.samples()) def set_practise(self, on=True): """ Turn practise mode on/off """ self.practise = on self.tuner = Tuner(self.path) #initiats at practise on, and stays. def message(self): """ Checks current frequency (at the adjustable oscillator) and sets a message to user """ font = pygame.font.Font(pygame.font.get_default_font(), 18) goal = self.stepToFreq(self.steps, self.guide_osc.frequency()) cents = self.hertzToCents(goal, self.pitch) self.screen.clear() if cents < 0: off = 'flat' elif cents > 0: off = 'sharp' msg = '' #ok? if cents > -self.acceptable_off and cents < self.acceptable_off: self.level += 1; self.setLevel(self.level) self.guide_osc.set_frequency(self.guide) msg = 'Well done! Just ' + str(round(cents,1)) + ' cents ' + off + '.' else: msg = str(round(cents,1)) + ' cents ' + off + '. Try again' if round(cents,1) == 0: msg = 'Amazing! Right on the spot!' #display message img = font.render(msg.upper(), True, BLACK) self.screen.blit(img, (self.center[0] - img.get_width()/2, 70)) #instruction message cont = 'PRESS ANY KEY TO CONTINUE.' font = pygame.font.Font(self.path + 'Actor-Regular.ttf', 10) self.screen.blit(font.render(cont, True, BLACK),(self.center[0] - font.size(cont)[0]/2, self.screen.get_height() - font.size(cont)[1] - 13)) self.draw() def run(self): """ main game loop. Always starts from level 1, and reinits the oscillators/audio channels """ if self.running: return False self.running = True degrees = 0 self.setLevel(1) # start from level 1 again self.initAudio() # init audio here for fresh oscillators clock = pygame.time.Clock() while self.running: if not self.pause: #start with checking each channels audio queue self.updateChannels() self.screen.clear() mx,my = pygame.mouse.get_pos() keystate = pygame.key.get_pressed() #fast increase frequency if keystate[K_UP]: if self.pitch < self.max_freq: self.pitch += 1.6#*= 1.01 #self.pitch *= 1.01 degrees += 1.3 self.knob[0].rotate(degrees) #fast decrease frequency elif keystate[K_DOWN]: if self.pitch > self.min_freq: self.pitch -= 1.6#/= 1.01 #self.pitch /= 1.01 degrees -= 1.3 self.knob[0].rotate(degrees) #slow decrease frequency elif keystate[K_LEFT]: if self.pitch > self.min_freq: self.pitch -= 0.1 degrees -= 0.2 self.knob[0].rotate(degrees) #slow increase frequency elif keystate[K_RIGHT]: if self.pitch < self.max_freq: self.pitch += 0.1 degrees += 0.2 self.knob[0].rotate(degrees) self.osc.set_frequency(self.pitch) for e in pygame.event.get(): if e.type == QUIT: self.running = False elif e.type == MOUSEBUTTONDOWN: #check back button if self.back[2].collidepoint(e.pos): self.running = False elif e.type == KEYUP: #unpause if self.pause: self.pause = False break elif e.key == K_RETURN: self.pause = True self.message() if not self.pause: #redraw screen self.draw() clock.tick(60) self.running = False return True #helpers def hertzToCents(self, a, b): try: return 1200 * math.log((b/float(a)), 2) except Exception as e: print e return 0 def posToDeg(self, pos): #not used """ Returns a positions degree from windows center """ degree = math.degrees(math.atan2(self.center[1]-pos[1], self.center[0]-pos[0])) + 180 if degree == 360.0: degree = 0 return round(degree) def randExclude(self, seq, low=0, high=24): """ returns a random integer seq: numbers to exclude (list) low: lowest int high: highest int """ rand = 0 while rand in seq: rand = random.randint(low, high) return rand def stepToFreq(self, step, frequency=False): """ returns a frequncy scale or a new frequency step: number of keys frequency: from frequency """ if not frequency: return math.pow(2, step/12.0) return frequency * math.pow(2, step/12.0) def freqToNote(self, freq): #not used """ Code for determining note name from frequency value. Code is written for equal temperament and A=440. Notes are displayed according to sharps. This can be overrided easily by changing the array definition below. Written by Firat Civaner (for mathlab) http://www.mathworks.com/matlabcentral/fileexchange/35330-frequency-to-note/content/freq2note.m return: A tuple with a string with notename + octave and frequency offset in cents """ A4 = 440 notenames = ['C' , 'C#', 'D' , 'D#' , 'E' , 'F' , 'F#', 'G' , 'G#' , 'A' , 'A#' , 'B' ] centdif = round( 1200 * math.log(freq/A4)/math.log(2)) notedif = round(centdif/100) if centdif % 100 > 50: notedif = notedif + 1 error = centdif-notedif*100 notenumber = notedif + 9 + 12*4 #count of half tones starting from C0. octavenumber = round((notenumber)/12) place = int(round(notenumber % 12 + 1)) if place < 0 or place > len(notenames)-1: print place return 'error' try: return (notenames[place]+str(octavenumber), error) except: return 'Error. Could not identify note'
class Game: """ The main game class. This deals with two oscillators, of which one is adjustable. The diffrence between those frequencies are measured and compared to the wanted interval. Margin of errors is given i cents. """ screen = None center = None #screen center instructions = None #instructions surface interval = None #interval surface result = None # surface for result displaying path = None #for resources #GUI elements knob = None knob_rect = None plate = None running = False #state check intevals = None #interval array guide_osc = None # guide note oscillator guide = None # guide_osc frequency osc = None # user ajustable oscillator guide_ch = None #Audio channel osc_ch = None #Audio channel pitch = None # osc frequency steps = 1 # number of musical notes. Level one starts at an octave prev_steps = [] #stores old game settings max_freq = 0 # 4 x base oscillator frequency (two octaves) min_freq = 0 # bace oscillator frequency level = 1 #level pause = False # pausing main loop practise = False tuner = None acceptable_off = 10 # how many cents off for a corrects answer? def __init__(self, gradient, path): """ gradient: A gradient object to act as background path: path to images """ self.screen = gradient self.center = self.screen.get_rect().center self.path = path # interval class self.intervals = Interval() self.instr_str = 'UP AND DOWN ARROWS COARSE TUNE. USE LEFT AND RIGHT FOR FINE ADJUSTMENT' self.conf_str = 'PRESS ENTER TO CONFIRM' self.setLevel(self.level) self.initGUI() #self.initAudio() def initGUI(self): """ Inits the graphical components """ #clear background self.screen.clear() self.screen.draw() #knob image img = pygame.image.load(self.path + 'knob.png') #plates self.plate = pygame.image.load(self.path + 'rust.png') self.knob = Knob(img) self.knob.set_plate(self.plate) #self.knob.set_shadow((-6,-4), 150, 25) knb_center = self.knob.get_rect().center self.knob = (self.knob, (self.center[0] - knb_center[0], self.center[1] - knb_center[1]) ) # also stores knob.rect at blit time self.center = self.screen.get_rect().center #"back" back_img = pygame.image.load(self.path + 'back.png') back_pos = (30, 30) #tuple width the image and it's position and a third element containting elements Rect. self.back = (back_img, (30, 30), self.screen.blit(back_img, back_pos)) #arrow arrow_img = pygame.image.load(self.path + 'arrow.png') self.arrow = (arrow_img, (self.center[0] - arrow_img.get_width() / 2, 104)) #instructions, texts instrs = [ 'UP', 'DOWN', 'FINE UP', 'FINE DOWN', 'PRESS ENTER TO CONFIRM' ] font = pygame.font.Font(self.path + 'Actor-Regular.ttf', 10) #instructions, key images key_images = pygame.Surface( (184, 69), pygame.SRCALPHA, 32 ) #collecting those images in a surface, for flexible positioning. key_images_cp = key_images.get_rect().center img = pygame.image.load(self.path + 'key.png') up = pygame.transform.rotozoom(img, 90, 1) key_images.blit( up, (key_images_cp[0] - up.get_size()[0] / 2, 0)) #up arrow key_images.blit( font.render(instrs[0], True, BLACK), (key_images_cp[0] - font.size(instrs[0])[0] / 2, 9)) #up text key_images.blit( font.render(instrs[3], True, BLACK), (0, key_images_cp[1] - font.size(instrs[3])[1] / 2)) #left text left = pygame.transform.rotozoom(img, 180, 1) key_images.blit(left, (font.size(instrs[3])[0] + 5, key_images_cp[1] - left.get_size()[1] / 2)) #left arrow right = img key_images.blit( right, (key_images.get_width() - font.size(instrs[3])[0] - 5 - right.get_size()[0], key_images_cp[1] - right.get_size()[1] / 2)) #right arrow (reflects left) key_images.blit(font.render(instrs[2], True, BLACK), (key_images.get_width() - font.size(instrs[3])[0] + 5 - right.get_size()[0], key_images_cp[1] - font.size(instrs[2])[1] / 2)) #right text key_images.blit( font.render(instrs[1], True, BLACK), (key_images_cp[0] - font.size(instrs[1])[0] / 2, 44)) #down text down = pygame.transform.rotozoom(img, 270, 1) key_images.blit(down, (key_images_cp[0] - down.get_size()[0] / 2, 69 - down.get_size()[1])) #up arrow #public parent container for instructions self.instructions = pygame.Surface((self.screen.get_width(), 115), pygame.SRCALPHA, 32) self.instructions.blit( key_images, (self.instructions.get_rect().center[0] - key_images_cp[0], 0)) self.instructions.blit( font.render(instrs[4], True, BLACK), (self.instructions.get_rect().center[0] - font.size(instrs[4])[0] / 2, key_images.get_height() + 20)) def initAudio(self): """ Inits the two oscillators and their channels. """ #guide tone self.guide_osc = Oscillator('sine', self.guide, BUFFER_SIZE) self.guide_ch = pygame.mixer.Channel(0) self.guide_ch.set_volume(0.9 / 2.0) #adjustable (the knob one), starts at same freq self.osc = Oscillator('sine', self.pitch, BUFFER_SIZE) self.osc_ch = pygame.mixer.Channel(1) self.osc_ch.set_volume(0.9 / 2.0) def setLevel(self, level): """ inits different levels """ lowest_freq = 220 # low limit # for use in levels > 4 rand_guide = self.stepToFreq(random.randint(0, 12), 220) # 220Hz < 440Hz in perfect notes. if level == 1: self.guide = 440 self.steps = 0 self.pitch = self.stepToFreq(1, self.guide) elif level == 2: self.guide = 440 self.steps = 12 self.pitch = self.stepToFreq(11, self.guide) elif level == 3: self.guide = 440 self.steps = 7 self.pitch = self.stepToFreq(6, self.guide) elif level == 4: self.guide = rand_guide self.steps = 5 init_rand = random.randint(0, 11) self.pitch = self.stepToFreq(init_rand, self.guide) elif level == 5: self.guide = rand_guide self.steps = self.randExclude(self.prev_steps + [5], 0, 12) init_rand = random.randint(0, 11) self.pitch = self.stepToFreq(11, self.guide) elif level == 6: self.guide = rand_guide self.steps = self.randExclude(self.prev_steps + [6]) init_rand = random.randint(0, 24) self.pitch = self.stepToFreq(11, self.guide) elif level >= 7: self.guide = rand_guide self.steps = random.randint(0, 24) # whole range init_rand = random.randint(0, 24) self.pitch = self.stepToFreq(11, self.guide) else: return False self.prev_steps.append( self.steps) #store, for unique intervals the first 6 levels # set min/max frequencies self.max_freq = self.guide * 4 # maximum frequency self.min_freq = self.guide - 20 # minimum frequency #set interval text self.setIntervalText() def setIntervalText(self): """ Text to display the wanted interval """ font = pygame.font.Font(pygame.font.get_default_font(), 18) img = font.render(self.intervals.at(self.steps), True, BLACK) #interval surface gets made every time function is called, this is done during pauses in main loop. The inefficiency should not be a problem. self.interval = pygame.Surface( (self.screen.get_width(), font.get_height()), SRCALPHA, 32) self.interval.blit(img, (self.center[0] - img.get_width() / 2, 0)) def draw(self): """ draw screen """ self.back = (self.back[0], self.back[1], self.screen.blit(self.back[0], self.back[1])) self.screen.blit(self.arrow[0], self.arrow[1]) self.screen.blit(self.knob[0], self.knob[1]) if not self.pause: self.screen.blit(self.interval, (0, 70)) self.screen.blit(self.instructions, (0, 285)) #practise mode? if self.practise is True: #display tuner goal = self.stepToFreq(self.steps, self.guide_osc.frequency()) cents = self.hertzToCents(goal, self.pitch) self.tuner.update(cents) self.screen.blit(self.tuner, (self.center[0] - self.tuner.center[0], 20)) self.screen.draw() def updateChannels(self): """ update audio queues """ if self.guide_ch.get_queue() == None: self.guide_ch.queue(self.guide_osc.samples()) if self.osc_ch.get_queue() == None: self.osc_ch.queue(self.osc.samples()) def set_practise(self, on=True): """ Turn practise mode on/off """ self.practise = on self.tuner = Tuner(self.path) #initiats at practise on, and stays. def message(self): """ Checks current frequency (at the adjustable oscillator) and sets a message to user """ font = pygame.font.Font(pygame.font.get_default_font(), 18) goal = self.stepToFreq(self.steps, self.guide_osc.frequency()) cents = self.hertzToCents(goal, self.pitch) self.screen.clear() if cents < 0: off = 'flat' elif cents > 0: off = 'sharp' msg = '' #ok? if cents > -self.acceptable_off and cents < self.acceptable_off: self.level += 1 self.setLevel(self.level) self.guide_osc.set_frequency(self.guide) msg = 'Well done! Just ' + str(round(cents, 1)) + ' cents ' + off + '.' else: msg = str(round(cents, 1)) + ' cents ' + off + '. Try again' if round(cents, 1) == 0: msg = 'Amazing! Right on the spot!' #display message img = font.render(msg.upper(), True, BLACK) self.screen.blit(img, (self.center[0] - img.get_width() / 2, 70)) #instruction message cont = 'PRESS ANY KEY TO CONTINUE.' font = pygame.font.Font(self.path + 'Actor-Regular.ttf', 10) self.screen.blit(font.render(cont, True, BLACK), (self.center[0] - font.size(cont)[0] / 2, self.screen.get_height() - font.size(cont)[1] - 13)) self.draw() def run(self): """ main game loop. Always starts from level 1, and reinits the oscillators/audio channels """ if self.running: return False self.running = True degrees = 0 self.setLevel(1) # start from level 1 again self.initAudio() # init audio here for fresh oscillators clock = pygame.time.Clock() while self.running: if not self.pause: #start with checking each channels audio queue self.updateChannels() self.screen.clear() mx, my = pygame.mouse.get_pos() keystate = pygame.key.get_pressed() #fast increase frequency if keystate[K_UP]: if self.pitch < self.max_freq: self.pitch += 1.6 #*= 1.01 #self.pitch *= 1.01 degrees += 1.3 self.knob[0].rotate(degrees) #fast decrease frequency elif keystate[K_DOWN]: if self.pitch > self.min_freq: self.pitch -= 1.6 #/= 1.01 #self.pitch /= 1.01 degrees -= 1.3 self.knob[0].rotate(degrees) #slow decrease frequency elif keystate[K_LEFT]: if self.pitch > self.min_freq: self.pitch -= 0.1 degrees -= 0.2 self.knob[0].rotate(degrees) #slow increase frequency elif keystate[K_RIGHT]: if self.pitch < self.max_freq: self.pitch += 0.1 degrees += 0.2 self.knob[0].rotate(degrees) self.osc.set_frequency(self.pitch) for e in pygame.event.get(): if e.type == QUIT: self.running = False elif e.type == MOUSEBUTTONDOWN: #check back button if self.back[2].collidepoint(e.pos): self.running = False elif e.type == KEYUP: #unpause if self.pause: self.pause = False break elif e.key == K_RETURN: self.pause = True self.message() if not self.pause: #redraw screen self.draw() clock.tick(60) self.running = False return True #helpers def hertzToCents(self, a, b): try: return 1200 * math.log((b / float(a)), 2) except Exception as e: print e return 0 def posToDeg(self, pos): #not used """ Returns a positions degree from windows center """ degree = math.degrees( math.atan2(self.center[1] - pos[1], self.center[0] - pos[0])) + 180 if degree == 360.0: degree = 0 return round(degree) def randExclude(self, seq, low=0, high=24): """ returns a random integer seq: numbers to exclude (list) low: lowest int high: highest int """ rand = 0 while rand in seq: rand = random.randint(low, high) return rand def stepToFreq(self, step, frequency=False): """ returns a frequncy scale or a new frequency step: number of keys frequency: from frequency """ if not frequency: return math.pow(2, step / 12.0) return frequency * math.pow(2, step / 12.0) def freqToNote(self, freq): #not used """ Code for determining note name from frequency value. Code is written for equal temperament and A=440. Notes are displayed according to sharps. This can be overrided easily by changing the array definition below. Written by Firat Civaner (for mathlab) http://www.mathworks.com/matlabcentral/fileexchange/35330-frequency-to-note/content/freq2note.m return: A tuple with a string with notename + octave and frequency offset in cents """ A4 = 440 notenames = [ 'C', 'C#', 'D', 'D#', 'E', 'F', 'F#', 'G', 'G#', 'A', 'A#', 'B' ] centdif = round(1200 * math.log(freq / A4) / math.log(2)) notedif = round(centdif / 100) if centdif % 100 > 50: notedif = notedif + 1 error = centdif - notedif * 100 notenumber = notedif + 9 + 12 * 4 #count of half tones starting from C0. octavenumber = round((notenumber) / 12) place = int(round(notenumber % 12 + 1)) if place < 0 or place > len(notenames) - 1: print place return 'error' try: return (notenames[place] + str(octavenumber), error) except: return 'Error. Could not identify note'
def __init__(self): self.acc = PVector() self.vel = PVector(random(-1, 1), random(-1, 1)) self.loc = PVector(random(width), random(height)) self.mass = random(8, 16) self.osc = Oscillator(self.mass * 2)
def init(self): self.osc = Oscillator(freq=1) self.osc2 = Oscillator(freq=5, zero=True, phase=20) self.amplitude = 0 self.add_parameter(name="amplitude", min=10, max=60)
class OscbarApp: """ Oscbar object """ def __init__(self): # config app_title = "Oscbar" interval = 2 # seconds per calibration step # initial oscillator settings self.wave_type = "sine_wave" self.amplitude = 0.5 self.frequency = 440 self.store_wave = None self.store_freq = None # object instances self.app = rumps.App(app_title, icon=APP_ICON) self.oct_timer = rumps.Timer( lambda sender, factor=2, max_freq=880, title='Octave Walk': self. advance_frequency(sender, factor, max_freq, title), interval) self.oct_thirds_timer = rumps.Timer( lambda sender, factor=(2**(1 / 3)), max_freq=880, title ='Octave Walk ⅓': self.advance_frequency( sender, factor, max_freq, title), interval) self.osc = Oscillator(self.wave_type, self.amplitude, self.frequency) # set up menu self.build_menu() self.osc_ready_menu() def build_menu(self): """ define menu, buttons, sliders """ # menu items self.start_button = rumps.MenuItem( # Start Osc title="Start Oscillator") self.stop_button = rumps.MenuItem( # Stop Osc title="Stop Oscillator") self.amp_title = rumps.MenuItem( # Volume title title=amp_title_format(self.amplitude), callback=None) self.amp_slider = rumps.SliderMenuItem( # Volume slider value=self.amplitude, min_value=0.0, max_value=1.0, callback=self.adj_amp, dimensions=(200, 20)) self.sine_wave_button = rumps.MenuItem( # Sine Wave title="Sine Wave", callback=self.set_sine_wave) self.square_wave_button = rumps.MenuItem( # Square Wave title="Square Wave", callback=self.set_square_wave) self.white_noise_button = rumps.MenuItem( # White Noise title="White Noise", callback=self.set_white_noise) self.pink_noise_button = rumps.MenuItem( # Pink Noise title="Pink Noise", callback=self.set_pink_noise) self.freq_title = rumps.MenuItem( # Frequency: title title=freq_title_format(self.frequency), callback=None) self.freq_slider = rumps.SliderMenuItem( # Frequency slider value=freq_to_slider(self.frequency), min_value=freq_to_slider(20), # 20Hz - 20kHz max_value=freq_to_slider(20000), callback=self.adj_freq, dimensions=(200, 20)) self.octave_button = rumps.MenuItem( # Octave Walk title="Octave Walk", callback=lambda sender, timer=self.oct_timer: self. begin_octave_walk(sender, timer)) self.octave_thirds_button = rumps.MenuItem( # Octave Walk 1/3 title="Octave Walk ⅓", callback=lambda sender, timer=self.oct_thirds_timer: self. begin_octave_walk(sender, timer)) #populate menu self.app.menu = [ self.start_button, self.stop_button, None, self.amp_title, self.amp_slider, None, self.sine_wave_button, self.square_wave_button, self.white_noise_button, self.pink_noise_button, None, self.freq_title, self.freq_slider, None, self.octave_button, self.octave_thirds_button, None ] # ------------------------ Menu Bar App: Menu UI Methods ----------------------- def remove_checkmark(self): """ clear wave type checkmarks from menu state """ for item in self.app.menu: if hasattr(self.app.menu[item], 'state'): if self.app.menu[item].state == 1: self.app.menu[item].state = 0 def osc_ready_menu(self): """ menu while not playing osc """ #self.app.title = "🎛" self.start_button.set_callback(self.start_osc) self.stop_button.set_callback(None) self.remove_checkmark() for item in self.app.menu: try: if self.osc.wave_type in self.app.menu[item].callback.__name__: self.app.menu[item].state = 1 except AttributeError: pass def osc_busy_menu(self): """ menu while playing osc """ #self.app.title = "🔊" self.start_button.set_callback(None) self.stop_button.set_callback(self.stop_osc) def wave_change_menu(self, sender): """ menu change when selecting new wave type """ self.remove_checkmark() sender.state = 1 # --------------------------- Menu Bar App: Callbacks -------------------------- def start_osc(self, sender): """ Start Oscillator callback """ self.osc_busy_menu() self.osc.play() def stop_osc(self, sender): """ Stop Oscillator callback """ self.osc_ready_menu() self.osc.stop() def set_sine_wave(self, sender): """ Sine Wave callback """ self.wave_change_menu(sender) self.osc.wave_type = 'sine_wave' def set_square_wave(self, sender): """ Square Wave callback """ self.wave_change_menu(sender) self.osc.wave_type = 'square_wave' def set_white_noise(self, sender): """ White Noise callback """ self.wave_change_menu(sender) self.osc.wave_type = 'white_noise' def set_pink_noise(self, sender): """ Pink Noise callback """ self.wave_change_menu(sender) self.osc.wave_type = 'pink_noise' def prep_calibration(self, wave_type, frequency): """ retain oscillator settings during calibration """ # stop osc if playing if not self.osc.stream is None: self.stop_osc(sender=None) # retain settings self.store_wave = self.osc.wave_type self.store_freq = self.osc.frequency # initial calibration settings self.osc.wave_type = wave_type self.osc.frequency = frequency def advance_frequency(self, sender, factor, max_freq, title): """ Increase frequency by factor until max frequency is reached, then stop the timer """ if self.osc.stream: self.stop_osc(sender=None) self.osc.frequency *= factor if self.osc.frequency > max_freq: self.oct_timer.stop() self.oct_thirds_timer.stop() # restore settings self.osc.wave_type = self.store_wave self.osc.frequency = self.store_freq self.osc_ready_menu() else: rumps.notification(title=title, subtitle=None, message=freq_title_format(self.osc.frequency), sound=False, icon=APP_ICON) self.osc.play() def begin_octave_walk(self, sender, timer): """ Octave Walk callback Walk up by octave: A0 (27.5 Hz) - A6 (1760 Hz) """ self.prep_calibration('sine_wave', 27.5) timer.start() def adj_freq(self, sender): """ Frequency slider callback """ frequency = slider_to_freq(self.freq_slider.value) self.freq_title.title = freq_title_format(frequency) # update title self.osc.frequency = frequency # update oscillator print( f'SLIDER ===> {self.freq_slider.value}, FREQ ===> {self.osc.frequency}' ) def adj_amp(self, sender): """ Amplitude slider callback """ self.amp_title.title = amp_title_format( self.amp_slider.value) # update title self.osc.amplitude = self.amp_slider.value # update oscillator print( f'SLIDER ===> {self.amp_slider.value}, AMP ===> {self.osc.amplitude}' ) def run(self): """ run it """ self.app.run()
import matplotlib.lines as mlines import numpy as np from matplotlib import animation from matplotlib import pyplot as plt from oscillator import Oscillator fig = plt.figure() ax = plt.axes(xlim=(0, 10), ylim=(-0.22, 0.22)) theta_line, = ax.plot([], [], lw=2, color="green") theta_dash_line, = ax.plot([], [], lw=2, color="blue") time_steps = 400 time_max = 10.0 osc = Oscillator() x = np.linspace(0, time_max, time_steps + 1) trajectory = osc.get_trajectory(time_max, time_steps) y = [position for position, velocity in trajectory] y_dash = [velocity for position, velocity in trajectory] def init(): theta_line.set_data([], []) plt.xlabel("Time", fontsize=13, family='monospace') plt.ylabel("Angular Displacement, Angular Velocity", fontsize=13, family='monospace') plt.title("Angular Displacement and Angular Velocity v/s Time",
def test_state_unchanged_after_zero_time(self): oscillator = Oscillator() self.assertListEqual(oscillator.state, list(oscillator.get_trajectory(0, 1)[0]))