#!/usr/bin/env python # coding: utf-8 # > This is one of the 100 recipes of the [IPython Cookbook](http://ipython-books.github.io/), the definitive guide to high-performance scientific computing and data science in Python. # # # 11.7. Creating a sound synthesizer in the notebook # 1. We import NumPy, matplotlib, and various IPython packages and objects. # In[ ]: import numpy as np import matplotlib.pyplot as plt from IPython.display import Audio, display, clear_output from IPython.html import widgets from functools import partial import matplotlib as mpl get_ipython().run_line_magic('matplotlib', 'inline') # 2. We define the sampling rate and the duration of the notes. # In[ ]: rate = 16000. duration = .5 t = np.linspace(0., duration, rate * duration) # 3. We create a function that generates and plays the sound of a note (sine function) at a given frequency, using NumPy and IPython's `Audio` class. # In[ ]: def synth(f): x = np.sin(f * 2. * np.pi * t) display(Audio(x, rate=rate, autoplay=True)) # 4. Here is the fundamental 440 Hz note. # In[ ]: synth(440) # 5. Now, we generate the note frequencies of our piano. The chromatic scale is obtained by a geometric progression with common ratio $2^{1/12}$. # In[ ]: keys = 'C,C#,D,D#,E,F,F#,G,G#,A,A#,B,C'.split(',') notes = zip(keys, 440. * 2 ** (np.arange(3, 3 + len(keys)) / 12.)) # 6. Finally, we create the piano with the notebook widgets. Each note is a button, and all buttons are contained in an horizontal box container. Clicking on one note plays a sound at the corresponding frequency. # In[ ]: container = widgets.ContainerWidget() buttons = [] for note, f in notes: button = widgets.ButtonWidget(description=note) def on_button_clicked(f, b): clear_output() synth(f) button.on_click(partial(on_button_clicked, f)) button.set_css({'width': '30px', 'height': '60px', 'padding': '0', 'color': ('black', 'white')['#' in note], 'background': ('white', 'black')['#' in note], 'border': '1px solid black', 'float': 'left'}) buttons.append(button) container.children = buttons display(container) container.remove_class('vbox') container.add_class('hbox') # > You'll find all the explanations, figures, references, and much more in the book (to be released later this summer). # # > [IPython Cookbook](http://ipython-books.github.io/), by [Cyrille Rossant](http://cyrille.rossant.net), Packt Publishing, 2014 (500 pages).