music/Waves.ipynb

275 lines
132 KiB
Text
Raw Permalink Normal View History

2018-03-08 08:09:39 -08:00
{
"cells": [
{
"cell_type": "code",
2018-03-27 07:21:39 -07:00
"execution_count": 2,
"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",
2018-03-27 07:21:39 -07:00
"Harmonics = 20\n",
2018-03-08 08:09:39 -08:00
"# Time in seconds.\n",
"Time = 2.0\n",
"# Plot resolution.\n",
2018-03-27 07:21:39 -07:00
"Steps = 400"
]
},
{
"cell_type": "code",
2018-03-27 07:21:39 -07:00
"execution_count": 8,
"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-27 07:21:39 -07:00
" return float(samples) / 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",
" '''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",
" # Get the frequencies for a DFT plot (this doesn't depend on the actual signal) based on the \n",
" # spacing of our samples.\n",
" freqs = np.fft.fftfreq(len(fft), d=sample_spacing())\n",
2018-03-08 08:09:39 -08:00
" \n",
" 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",
" plt.axhline(color='#666666', linewidth=0.75)\n",
" 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",
" plt.bar(freqs, mags)"
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-27 07:21:39 -07:00
"execution_count": 9,
2018-03-08 08:09:39 -08:00
"metadata": {},
2018-03-27 07:21:39 -07:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x432 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2018-03-08 08:09:39 -08:00
"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",
"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-27 07:21:39 -07:00
"execution_count": 4,
2018-03-08 08:09:39 -08:00
"metadata": {},
2018-03-27 07:21:39 -07:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x432 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2018-03-08 08:09:39 -08:00
"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",
"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-27 07:21:39 -07:00
"execution_count": 5,
2018-03-08 08:09:39 -08:00
"metadata": {},
2018-03-27 07:21:39 -07:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x432 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2018-03-08 08:09:39 -08:00
"source": [
"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-27 07:21:39 -07:00
"execution_count": 6,
2018-03-08 08:09:39 -08:00
"metadata": {},
2018-03-27 07:21:39 -07:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x432 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2018-03-08 08:09:39 -08:00
"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",
"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-27 07:21:39 -07:00
"execution_count": 7,
2018-03-08 08:09:39 -08:00
"metadata": {},
2018-03-27 07:21:39 -07:00
"outputs": [
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 720x432 with 2 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
2018-03-08 08:09:39 -08:00
"source": [
2018-03-27 07:21:39 -07:00
"def triangle(domain, freq=1, h=Harmonics):\n",
2018-03-08 08:09:39 -08:00
" def label(i):\n",
" return 2. * i + 1.\n",
2018-03-27 07:21:39 -07:00
" harmonics = np.asarray([((-1) ** h) * (label(h) ** -2) * sine(domain, freq=freq * label(h)) for h in range(h)])\n",
2018-03-08 08:09:39 -08:00
" wave = np.sum(harmonics, axis=0)\n",
" return wave\n",
"\n",
"wave = triangle(time_space())\n",
"plot_signal_and_spectrum(time_space(), wave)"
2018-03-08 08:09:39 -08:00
]
2018-03-27 07:21:39 -07:00
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
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",
2018-03-27 07:21:39 -07:00
"version": "3.6.4"
2018-03-08 08:09:39 -08:00
}
},
"nbformat": 4,
"nbformat_minor": 2
}