{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Interpolation/Fractional Delay/Resampling" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "[back to overview page](index.ipynb)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "WARNING: this is work-in-progress!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Digital Audio Resampling Home Page: https://ccrma.stanford.edu/~jos/resample/\n", "\n", "Delay-Line and Signal Interpolation: https://ccrma.stanford.edu/~jos/pasp06/Delay_Line_Signal_Interpolation.html\n", "\n", "Time-Varying Delay Effects: https://ccrma.stanford.edu/~jos/pasp06/Time_Varying_Delay_Effects.html\n", "\n", "MUS420/EE367A Lecture 4A: Interpolated Delay Lines, Ideal Bandlimited Interpolation, and Fractional Delay Filter Design: https://ccrma.stanford.edu/~jos/Interpolation/Welcome.html" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "TODO: a lot of explanations\n", "\n", "For an introduction on NumPy and how to create simple signals, see [Creating Simple Audio Signals](http://nbviewer.ipython.org/urls/raw.github.com/mgeier/python-audio/master/simple-signals.ipynb)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "import numpy as np" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "First, let's set the sampling rate we'll be using:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "fs = 44100 # Hz" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "A nice sine tone as test signal ..." ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "duration = 2 # seconds\n", "frequency = 440 # Hz\n", "\n", "t = np.arange(int(duration * fs)) / fs\n", "sine = np.sin(2 * np.pi * frequency * t)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(sine[:100])\n", "plt.ylim(-1.1, 1.1);" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "# TODO: fade in/out!\n", "# TODO: write WAV file" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "According to [JOS](https://ccrma.stanford.edu/~jos/pasp06/Linear_Interpolation.html):\n", "$\\hat{y}(n+\\eta) = (1-\\eta) \\cdot y(n) + \\eta \\cdot y(n+1)$\n", "\n", "That's a one-zero FIR filter.\n", "\n", "TODO: block diagram like in [JOS](https://ccrma.stanford.edu/~jos/pasp06/Fractional_Delay_Filtering_Linear.html)?" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "def dumb_linear_interpolation(x, fraction):\n", " \"This is a very dumb implementation!\"\n", " x = np.asarray(x)\n", " assert x.ndim == 1, \"x must be one-dimensional!\"\n", " \n", " y_len = len(x) - 1\n", " y = np.empty(y_len)\n", " for i in range(y_len):\n", " y[i] = (1 - fraction) * x[i] + fraction * x[i + 1]\n", " return y" ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "88199" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "sine2 = dumb_linear_interpolation(sine, 0.5)\n", "\n", "len(sine2)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Note: length is one sample less" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(sine2[:100])\n", "plt.ylim(-1.1, 1.1);" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Looks OK? Sounds OK?" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "# TODO: same with noise, listen to both versions (WAV file) -> low-pass?" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "OK, this is actually FIR filtering (TODO: explain), so we can do it with a convolution:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "# TODO: explain mode='valid'\n", "\n", "sine3 = np.convolve(sine, [0.5, 0.5], mode='valid')" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "0.0" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "max(abs(sine2 - sine3))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "When I tried it, there wasn't even a rounding error. YMMV." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Let's check the frequency response of our interpolation filter to check if it's really a low-pass filter." ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "# TODO: better function to display frequency response?\n", "# TODO: use scipy.signal.freqz()?\n", "# TODO: in dB, log frequency?\n", "# TODO: x-axis: frequencies (np.fftfreq()?)\n", "\n", "fftlength = 1000\n", "plt.plot(abs(np.fft.rfft([0.5, 0.5], fftlength)));" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Yes, that looks like a low-pass filter!" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(0, 1.1)" ] }, "execution_count": 13, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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\n", "text/plain": [ "
" ] }, "metadata": { "needs_background": "light" }, "output_type": "display_data" } ], "source": [ "plt.plot(abs(np.fft.rfft(np.column_stack((\n", " [1 , 0 ],\n", " [0.9, 0.1],\n", " [0.8, 0.2],\n", " [0.7, 0.3],\n", " [0.6, 0.4],\n", " [0.5, 0.5])), fftlength, axis=0)))\n", "plt.ylim(0, 1.1)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "TODO: plot phase delay like in [JOS](https://ccrma.stanford.edu/~jos/pasp06/Fractional_Delay_Filtering_Linear.html)?" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [], "source": [ "# TODO: many more things!" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "TODO: [One-Multiply Linear Interpolation](https://ccrma.stanford.edu/~jos/pasp06/One_Multiply_Linear_Interpolation.html)?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "TODO: [First-Order Allpass Interpolation](https://ccrma.stanford.edu/~jos/pasp06/First_Order_Allpass_Interpolation.html)?" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": {}, "source": [ "

\n", " \n", " \"CC0\"\n", " \n", "
\n", " To the extent possible under law,\n", " the person who associated CC0\n", " with this work has waived all copyright and related or neighboring\n", " rights to this work.\n", "

" ] } ], "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.7.4" } }, "nbformat": 4, "nbformat_minor": 4 }