{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "> 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.\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 11.7. Creating a sound synthesizer in the notebook" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "1. We import NumPy, matplotlib, and various IPython packages and objects." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "from IPython.display import Audio, display, clear_output\n", "from IPython.html import widgets\n", "from functools import partial\n", "import matplotlib as mpl\n", "%matplotlib inline\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "2. We define the sampling rate and the duration of the notes." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "rate = 16000.\n", "duration = .5\n", "t = np.linspace(0., duration, rate * duration)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "def synth(f):\n", " x = np.sin(f * 2. * np.pi * t)\n", " display(Audio(x, rate=rate, autoplay=True))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "4. Here is the fundamental 440 Hz note." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "synth(440)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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}$." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "keys = 'C,C#,D,D#,E,F,F#,G,G#,A,A#,B,C'.split(',')\n", "notes = zip(keys, 440. * 2 ** (np.arange(3, 3 + len(keys)) / 12.))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "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." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false }, "outputs": [], "source": [ "container = widgets.ContainerWidget()\n", "buttons = []\n", "for note, f in notes:\n", " button = widgets.ButtonWidget(description=note)\n", " def on_button_clicked(f, b):\n", " clear_output()\n", " synth(f)\n", " button.on_click(partial(on_button_clicked, f))\n", " button.set_css({'width': '30px', \n", " 'height': '60px',\n", " 'padding': '0',\n", " 'color': ('black', 'white')['#' in note],\n", " 'background': ('white', 'black')['#' in note],\n", " 'border': '1px solid black',\n", " 'float': 'left'})\n", " buttons.append(button)\n", "container.children = buttons\n", "display(container)\n", "container.remove_class('vbox')\n", "container.add_class('hbox')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "> You'll find all the explanations, figures, references, and much more in the book (to be released later this summer).\n", "\n", "> [IPython Cookbook](http://ipython-books.github.io/), by [Cyrille Rossant](http://cyrille.rossant.net), Packt Publishing, 2014 (500 pages)." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.4.2" } }, "nbformat": 4, "nbformat_minor": 0 }