2018-03-08 08:09:39 -08:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
2018-03-08 09:37:06 -08:00
"metadata": {},
2018-03-08 08:09:39 -08:00
"outputs": [],
"source": [
"import matplotlib\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"\n",
"# Show plots inline.\n",
"%matplotlib inline\n",
"\n",
"# Number of harmonics to include in subsequent plots.\n",
"Harmonics = 10\n",
"# Time in seconds.\n",
"Time = 2.0\n",
"# Plot resolution.\n",
2018-03-08 09:37:06 -08:00
"Steps = 200"
]
},
{
"cell_type": "code",
2018-03-08 20:39:28 -08:00
"execution_count": 23,
2018-03-08 09:37:06 -08:00
"metadata": {
"scrolled": true
},
"outputs": [],
"source": [
2018-03-08 08:09:39 -08:00
"# Array of step values.\n",
"def time_space(sec=Time, samples=Steps):\n",
" '''An array of equally spaced samples over a period of time.'''\n",
" # One extra sample to also include the endpoint.\n",
" return np.linspace(0, sec, num=samples + 1)\n",
"\n",
"def sample_rate(sec=Time, samples=Steps):\n",
" '''Sampling rate in samples per second.'''\n",
2018-03-08 09:37:06 -08:00
" return float(samples + 1) / float(sec)\n",
"\n",
"def sample_spacing(sec=Time, samples=Steps):\n",
" '''Time between samples.'''\n",
" return float(sec) / float(samples + 1)\n",
2018-03-08 08:09:39 -08:00
"\n",
"def frequency_spectrum(data):\n",
2018-03-08 09:37:06 -08:00
" '''Perform an FFT on `data`.'''\n",
" # Get the signal frequencies.\n",
" fft = np.abs(np.fft.fft(data))\n",
2018-03-08 08:09:39 -08:00
" \n",
2018-03-08 09:37:06 -08:00
" # Get the frequencies for a DFT plot (this doesn't depend on the actual signal) based on the \n",
" # spacing of our samples.\n",
2018-03-08 20:39:28 -08:00
" freqs = np.fft.fftfreq(length, d=sample_spacing())\n",
2018-03-08 08:09:39 -08:00
" \n",
2018-03-08 09:37:06 -08:00
" return freqs, fft\n",
"\n",
"def plot_signal_and_spectrum(domain, data):\n",
" '''Plot the signal and spectrum in a stacked plot.'''\n",
2018-03-08 13:41:31 -08:00
" plt.figure(figsize=(10,6))\n",
" plt.subplot(211)\n",
2018-03-08 17:09:07 -08:00
" plt.axhline(color='#666666', linewidth=0.75)\n",
2018-03-08 09:37:06 -08:00
" plt.plot(domain, data)\n",
2018-03-08 08:09:39 -08:00
" \n",
2018-03-08 13:41:31 -08:00
" num_freqs = Harmonics * 2\n",
2018-03-08 20:39:28 -08:00
" freqs, mags = (x[:num_freqs] for x in frequency_spectrum(data))\n",
2018-03-08 13:41:31 -08:00
" plt.subplot(212)\n",
" plt.xticks(range(num_freqs))\n",
2018-03-08 20:39:28 -08:00
" plt.bar(freqs[:num_freqs], mags[:num_freqs])"
2018-03-08 08:09:39 -08:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Basic Waves"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Sine Wave\n",
"\n",
"Sine waves are easy. 😁 The have a single frequency, and no harmonics."
]
},
{
"cell_type": "code",
2018-03-08 20:39:28 -08:00
"execution_count": 24,
2018-03-08 08:09:39 -08:00
"metadata": {},
"outputs": [
2018-03-08 20:39:28 -08:00
{
"ename": "NameError",
"evalue": "name 'length' is not defined",
"output_type": "error",
"traceback": [
"\u001b[0;31m---------------------------------------------------------------------------\u001b[0m",
"\u001b[0;31mNameError\u001b[0m Traceback (most recent call last)",
"\u001b[0;32m<ipython-input-24-e9d29215ed5e>\u001b[0m in \u001b[0;36m<module>\u001b[0;34m()\u001b[0m\n\u001b[1;32m 5\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 6\u001b[0m \u001b[0mwave\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0msine\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime_space\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m----> 7\u001b[0;31m \u001b[0mplot_signal_and_spectrum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mtime_space\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mwave\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m",
"\u001b[0;32m<ipython-input-23-fdf3932b5a6a>\u001b[0m in \u001b[0;36mplot_signal_and_spectrum\u001b[0;34m(domain, data)\u001b[0m\n\u001b[1;32m 32\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 33\u001b[0m \u001b[0mnum_freqs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mHarmonics\u001b[0m \u001b[0;34m*\u001b[0m \u001b[0;36m2\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 34\u001b[0;31m \u001b[0mfreqs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mmags\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0;34m(\u001b[0m\u001b[0mx\u001b[0m\u001b[0;34m[\u001b[0m\u001b[0;34m:\u001b[0m\u001b[0mnum_freqs\u001b[0m\u001b[0;34m]\u001b[0m \u001b[0;32mfor\u001b[0m \u001b[0mx\u001b[0m \u001b[0;32min\u001b[0m \u001b[0mfrequency_spectrum\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mdata\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 35\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0msubplot\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;36m212\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 36\u001b[0m \u001b[0mplt\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mxticks\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mrange\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mnum_freqs\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;32m<ipython-input-23-fdf3932b5a6a>\u001b[0m in \u001b[0;36mfrequency_spectrum\u001b[0;34m(data)\u001b[0m\n\u001b[1;32m 20\u001b[0m \u001b[0;31m# Get the frequencies for a DFT plot (this doesn't depend on the actual signal) based on the\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 21\u001b[0m \u001b[0;31m# spacing of our samples.\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0;32m---> 22\u001b[0;31m \u001b[0mfreqs\u001b[0m \u001b[0;34m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfft\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfftfreq\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mlength\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0md\u001b[0m\u001b[0;34m=\u001b[0m\u001b[0msample_spacing\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m)\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n\u001b[0m\u001b[1;32m 23\u001b[0m \u001b[0;34m\u001b[0m\u001b[0m\n\u001b[1;32m 24\u001b[0m \u001b[0;32mreturn\u001b[0m \u001b[0mfreqs\u001b[0m\u001b[0;34m,\u001b[0m \u001b[0mfft\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n",
"\u001b[0;31mNameError\u001b[0m: name 'length' is not defined"
]
},
2018-03-08 08:09:39 -08:00
{
"data": {
2018-03-08 20:39:28 -08:00
"image/png": "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
2018-03-08 08:09:39 -08:00
"text/plain": [
2018-03-08 20:39:28 -08:00
"<Figure size 720x432 with 1 Axes>"
2018-03-08 08:09:39 -08:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"# Sine wave.\n",
"\n",
"def sine(domain, freq=1.0):\n",
" return np.sin(2.0 * np.pi * freq * domain)\n",
"\n",
"wave = sine(time_space())\n",
2018-03-08 09:37:06 -08:00
"plot_signal_and_spectrum(time_space(), wave)"
2018-03-08 08:09:39 -08:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Saw Wave\n",
"\n",
"Saw waves consist of every integer harmonic _n_ above the fundamental frequency, where that harmonic's amplitude is n<sup>-1</sup>."
]
},
{
"cell_type": "code",
2018-03-08 20:39:28 -08:00
"execution_count": 4,
2018-03-08 08:09:39 -08:00
"metadata": {},
"outputs": [
2018-03-08 20:39:28 -08:00
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/eryn/Library/Python/3.6/lib/python/site-packages/matplotlib/transforms.py:841: ComplexWarning: Casting complex values to real discards the imaginary part\n",
" points = np.array(args, dtype=float).reshape(2, 2)\n"
]
},
2018-03-08 08:09:39 -08:00
{
"data": {
2018-03-08 20:39:28 -08:00
"image/png": "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
2018-03-08 08:09:39 -08:00
"text/plain": [
2018-03-08 13:41:31 -08:00
"<Figure size 720x432 with 2 Axes>"
2018-03-08 08:09:39 -08:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def saw(domain, freq=1):\n",
" harmonics = np.asarray([1.0 / h * sine(domain, freq=freq * h) for h in range(1, Harmonics)])\n",
" wave = np.sum(harmonics, axis=0)\n",
" return wave\n",
"\n",
"wave = saw(time_space())\n",
2018-03-08 09:37:06 -08:00
"plot_signal_and_spectrum(time_space(), wave)"
2018-03-08 08:09:39 -08:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"You can invert a saw wave to get what many synths call a \"blade\" wave. Instead of gradually falling and then spiking up, blade waves gradually rise and the sharply fall."
]
},
{
"cell_type": "code",
2018-03-08 17:09:07 -08:00
"execution_count": 5,
2018-03-08 08:09:39 -08:00
"metadata": {},
"outputs": [
2018-03-08 20:39:28 -08:00
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/eryn/Library/Python/3.6/lib/python/site-packages/matplotlib/transforms.py:841: ComplexWarning: Casting complex values to real discards the imaginary part\n",
" points = np.array(args, dtype=float).reshape(2, 2)\n"
]
},
2018-03-08 08:09:39 -08:00
{
"data": {
2018-03-08 20:39:28 -08:00
"image/png": "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
2018-03-08 08:09:39 -08:00
"text/plain": [
2018-03-08 13:41:31 -08:00
"<Figure size 720x432 with 2 Axes>"
2018-03-08 08:09:39 -08:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
2018-03-08 09:37:06 -08:00
"plot_signal_and_spectrum(time_space(), -1 * saw(time_space()))"
2018-03-08 08:09:39 -08:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Square Wave\n",
"\n",
"Square waves are made of every other harmonic above the fundamental frequency. Again, the amplitude of each harmonic _n_ is _1 / n_."
]
},
{
"cell_type": "code",
2018-03-08 17:09:07 -08:00
"execution_count": 6,
2018-03-08 08:09:39 -08:00
"metadata": {},
"outputs": [
2018-03-08 20:39:28 -08:00
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/eryn/Library/Python/3.6/lib/python/site-packages/matplotlib/transforms.py:841: ComplexWarning: Casting complex values to real discards the imaginary part\n",
" points = np.array(args, dtype=float).reshape(2, 2)\n"
]
},
2018-03-08 08:09:39 -08:00
{
"data": {
2018-03-08 20:39:28 -08:00
"image/png": "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
2018-03-08 08:09:39 -08:00
"text/plain": [
2018-03-08 13:41:31 -08:00
"<Figure size 720x432 with 2 Axes>"
2018-03-08 08:09:39 -08:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def square(domain, freq=1):\n",
" harmonics = np.asarray([1.0 / h * sine(domain, freq=freq * h) for h in range(1, Harmonics, 2)])\n",
" wave = np.sum(harmonics, axis=0)\n",
" return wave\n",
"\n",
"wave = square(time_space())\n",
2018-03-08 09:37:06 -08:00
"plot_signal_and_spectrum(time_space(), wave)"
2018-03-08 08:09:39 -08:00
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Triangle Wave"
]
},
{
"cell_type": "code",
2018-03-08 17:09:07 -08:00
"execution_count": 7,
2018-03-08 08:09:39 -08:00
"metadata": {},
"outputs": [
2018-03-08 20:39:28 -08:00
{
"name": "stderr",
"output_type": "stream",
"text": [
"/Users/eryn/Library/Python/3.6/lib/python/site-packages/matplotlib/transforms.py:841: ComplexWarning: Casting complex values to real discards the imaginary part\n",
" points = np.array(args, dtype=float).reshape(2, 2)\n"
]
},
2018-03-08 08:09:39 -08:00
{
"data": {
2018-03-08 20:39:28 -08:00
"image/png": "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
2018-03-08 08:09:39 -08:00
"text/plain": [
2018-03-08 13:41:31 -08:00
"<Figure size 720x432 with 2 Axes>"
2018-03-08 08:09:39 -08:00
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"def triangle(domain, freq=1):\n",
" def label(i):\n",
" return 2. * i + 1.\n",
" harmonics = np.asarray([((-1) ** h) * (label(h) ** -2) * sine(domain, freq=freq * label(h)) for h in range(Harmonics)])\n",
" wave = np.sum(harmonics, axis=0)\n",
" return wave\n",
"\n",
"wave = triangle(time_space())\n",
2018-03-08 09:37:06 -08:00
"plot_signal_and_spectrum(time_space(), wave)"
2018-03-08 08:09:39 -08:00
]
}
],
"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.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}