{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "*This post was entirely written using the IPython notebook. Its content is BSD-licensed. You can see a static view or download this notebook with the help of nbviewer at [20160907_ImpulseResponses.ipynb](http://nbviewer.ipython.org/urls/raw.github.com/flothesof/posts/master/20160907_ImpulseResponses.ipynb).*" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In this notebook, we're going to explore the fascinating world of impulse responses. This blog post is inspired by many interesting projects of Allen Downey and in particular [this student project of his](https://t.co/XV1a3o76Q7). " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# What's an impulse response?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In many fields, the output of a system can be represented as the transformation of an input by a function, which we will call G. Symbollically, we would write this:\n", "\n", "$$\n", "y = G * x\n", "$$\n", "\n", "It turns out that if you choose G wisely, you can solve many problems of physics. The name G is chosen after George Green, who invented the concept. For a good introduction about Green's functions, I recommend this [Wolfram Blog entry](http://blog.wolfram.com/2016/03/31/new-in-the-wolfram-language-greenfunction-and-applications-in-electricity-odes-and-pdes/).\n", "\n", "Green functions come in many variants, depending on the problem to be solved, see [Wikipedia](https://en.wikipedia.org/wiki/Green%27s_function). In this posting, I propose to do the followine:\n", "\n", "- demonstrate the use of an impulse response on an audio file for different environments\n", "- transform the chunk of a song to something that gives the listener an impression to move in space\n", "\n", "First, let's introduce the theory background we'll need to perform our task." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Theory " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Actually, we need to introduce two theory items in this notebook: the convolution theorem, which is a classic signal processing way of teaching and the wave equation solution using a Green's function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## The convolution theorem " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The convolution theorem states that to apply a certain function G, I can use the Fourier frequency space to do it." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Solving the wave equation... in two dimensions! " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "All sounds that move through space obey the wave equation. It turns out that the wave equation can be solved with the following Green's function: \n", "\n", "$$\n", "G(t, \\rho) = {\\displaystyle {\\frac {1}{2\\pi c{\\sqrt {c^{2}t^{2}-\\rho ^{2}}}}}\\Theta (t-\\rho /c)}\n", "$$\n", "\n", "Here $\\rho$ is the distance to the receiving point, $c$ is the celerity of the medium and ${\\displaystyle \\Theta (t)}$ is the Heaviside step function." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Applying an impulse response to a sound" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "As explained above, let's now apply an impulse response to a sound. We will use a sound from FreeSound to test our example. First, we need to download our sound as a WAV file to work with it. To do this, we write a function that downloads it from the internet, stores it in a temporary file and uses FFMpeg to convert to WAV:" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import urllib\n", "import tempfile\n", "\n", "def download_mp3_as_np_array(url):\n", " \"Downloads a mp3 file and converts it to a numpy array.\"\n", " pass" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's now download the sound segment that we will use in this post:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true }, "outputs": [], "source": [ "snd = 0" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": true }, "outputs": [], "source": [] } ], "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.5.2" } }, "nbformat": 4, "nbformat_minor": 0 }