music/waves.ipynb

465 lines
132 KiB
Text
Raw Normal View History

2018-03-08 08:09:39 -08:00
{
"cells": [
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"scrolled": true
},
"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",
"Steps = 200\n",
"\n",
"# 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",
" return (samples + 1) / float(sec)\n",
"\n",
"def frequency_spectrum(data):\n",
" '''Perform an FFT on `data`. Return the max frequency in Hz, and the raw data, suitable for plotting.'''\n",
" fft = np.fft.fft(data)\n",
" # We only need to use half of the FFT because FFT data mirrors itself across the middle. (Or something? IDK?)\n",
" fft_len = int(len(fft) / 2) \n",
" \n",
" # Get the frequency of coefficients in the FFT.\n",
" freqs = np.fft.fftfreq(fft_len)\n",
" \n",
" # Get the highest frequency in the FFT\n",
" max_idx = np.argmax(np.abs(fft))\n",
" max_freq = fft[max_idx]\n",
" \n",
" # Convert that frequency above into Hz.\n",
" max_freq_hz = abs(max_freq * sample_rate() ** -1)\n",
" \n",
" out = np.abs(fft[:fft_len - 1] * sample_rate())\n",
" return max_freq_hz, out"
]
},
{
"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",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x104730358>]"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"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",
"plt.plot(time_space(), wave)"
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"max: 0.9973405302244392 Hz\n"
]
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x104794550>]"
]
},
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"max_hz, spectrum = frequency_spectrum(wave)\n",
"print(\"max: {} Hz\".format(max_hz))\n",
"plt.plot(spectrum[:Harmonics], 'x')"
]
},
{
"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",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x10451f908>]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"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",
"plt.plot(time_space(), wave)"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"max: 1.0036806672579326 Hz\n"
]
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1044eec50>]"
]
},
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"max_hz, spectrum = frequency_spectrum(wave)\n",
"print(\"max: {} Hz\".format(max_hz))\n",
"plt.plot(spectrum[:Harmonics], 'x')"
]
},
{
"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",
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x104946940>]"
]
},
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAYAAAAD8CAYAAAB+UHOxAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMi4wLCBodHRwOi8vbWF0cGxvdGxpYi5vcmcvFvnyVgAAIABJREFUeJzt3Xd4XOWZ8P/vM1WaUbUtybLkbuMKNrYw2Jga01JwCCVAQkkgDkuym02y72+Tiw27SbZk97ebzfJClpBAIITQk2BKDKYXY2PZuEiWbclVvVq9jGbmef+YkSzbKiPNzDlT7s916WJ0ztGcm/E5cz/tPI/SWiOEECL5WMwOQAghhDkkAQghRJKSBCCEEElKEoAQQiQpSQBCCJGkJAEIIUSSkgQghBBJShKAEEIkKUkAQgiRpGxmBzCaKVOm6FmzZpkdhhBCxI0dO3Y0aa1zQjk2phPArFmzKC4uNjsMIYSIG0qpY6EeK01AQgiRpCQBCCFEkpIEIIQQSUoSgBBCJClJAEIIkaQkAQghRJKSBCCEEElKEoAQpznR5eHZ7cfx+2W5VBF5/T4/v996jB6Pz+xQJAEIcbr/fOMAf//iXrYcajY7FJGAnt1eyT/8uYSntoX8vFbUSAIQYoiGjl6e31EFwHPFlSZHIxKN1+fnV+8fAgKJQGtza5mSAIQY4tEPj+D1+blsQQ6bSuto6+43OySRQF7dW0tlSw/rFuVS3tDJrspWU+ORBCBEkNaa54uruGrJVP7uqgV4vH7+vKva7LBEAnl2eyVzprj5+ZeXk2q3ml7LlAQgRFB1aw8tXR4unDeFJdMymTXZxZZDTWaHJRKE36/ZW9XGmnmTyUixc8lZOab3M0kCECKopLodgKUFmQDMmOymprXXzJBEAqk80U1Hn5el0wLX18wpLmpbe00dbSYJQIigkuo2rBbFwqnpABRkpVLd2mNyVCJRnF7AKMxKxePz09TZZ1pMkgCECCqpaWN+bhopdisAhdmptHR56PZ4TY5MJIKSmjbsVsX8vDQACrJTAagysZARkQSglHpMKdWglCoZYf+lSqk2pdSu4M/9kTivEJGitaakuo0lweo5BGoAgDQDiYgoqW7jrLx0nLZAAWNa8PqqPhHnCQB4HLh6jGM+0FovD/78JELnFSIiGjr6aOr0sLQgY3Db4A0qzUAiTFprSmvaB9v/4WQBw8zrKyIJQGv9PtASifcSwgwl1W3AyfZZOFlFN7OEJhJDbVsvLV2nFjDSU+xkpNioifcEEKLVSqndSqm/KKWWjHSQUmqDUqpYKVXc2NhoYHgimZXVBjroBjqAAfLSnVgtytQbVCSGgetr8bSMU7ZPy0pNiCagsewEZmqtlwH/F/jzSAdqrR/RWhdprYtyckJa2F6IsJU3dDItM4X0FPvgNpvVwtSMFGkCEmErb+gEYF5u+inbC7PNHWlmSALQWrdrrTuDr18D7EqpKUacW4hQVDR0Mi8v/YztBdnmltBEYqho6CQ33Ulmqv2U7QXJUANQSk1VSqng61XB88pUiyIm+P2aQ42dzM9NO2OfPAsgIqG8oZN5w11f2al09Hlp7zVnzilbJN5EKfU0cCkwRSlVBfwjYAfQWj8M3AD8lVLKC/QAN2uzp8ETIqi6tYfefv/wN2hWKnXtvXh9fmxWeWxGjJ/WmkMNnVy/ouCMfUOHgmbk28/YH20RSQBa61vG2P8g8GAkziVEpJU3dAAMXwPITsXn19R39A0O2xNiPOrae+ns845YwIBAAliUn3HG/miTIo1IehWDHXRn3qA5aU4Amk18XF/Et/L64TuAAXLSg9dXlznXlyQAkfTK6zuZkuYky+U4Y1+WK1Atb5V1AcQEjVbAGLjmzLq+JAGIpFcxQgcwDLlBeyQBiIkpb+gky2VnStqZBQy3w4rdqky7viQBiKSmtaaifvgRGnCyBtDW7TEyLJFAKho6mJeTRnAg5CmUUmSmOqQGIIQZqk700NHnZWH+me2zwOC47RPSBCQmQGvN/tqOEa8vCBQyWk0qYEgCEElt4BH9kUZg2K0W0pw26QMQEzJQwBhthE9Wql1qAEKYoay2A6VOnQPodJmpdlp7pAlIjN++MQoYEKwBSB+AEMbbV9vGrMluXI6RH4nJctlpkxqAmICy2vYQChgO0/qYJAGIpFZW28HiMR7AyXY5ZBSQmJCy2nZmj1HAyJYagBDG6+jt53hLN4tG6aADyHTZOSGjgMQElNV2jPmEb5bLTrfHR5/XZ1BUJ0kCEEnrQF1gCogxb9BUaQIS4xd6ASPwfIAZ15gkAJGQ9lS18tKuavz+keccDKWDDk520sn8hWJAZUs3f9h2nN7+kUvt+8dRwABzHjaMyGRwQsSS3350hH95tQyvX/N8cRW/uHk5U4Jz+gy1paKZ/MwU8jNTRn2/rFQHPr+ms897yoIxIjm9VVbPd5/dRXuvl99+dISHvrKCs4ZZS2JLRTNKwbkzskd9PzOnG5EagEgonxxp4ccv7+PSBbn8+NolbD/awo/+XHLGcf0+Px9VNHHpgpxhn9AcSuYDEgMaOnr5q6d2Mn2Si/+6cRknuvu596mdeLz+M45972AD5xRmMcl95hQQQ2UPzgdkfD+TJACRUH713iEmuR08eOu53LFmFn/zmfn8paSOdw40nHLcp8db6ejzcslZYy87avaEXSJ2PLHlKP0+Pw/euoLrVxby/99wDhUNnfzmw8OnHNfa7WFXZWtI19fA0+ZSAxAiDOX1Hby1v4HbV88kxW4F4BsXzWFujpt/fKn0lPba9w42YLUo1swbe2XSwRqAPAyW1Lr6vPx+63GuWjyV2VPcAFy2MJerluTxwFvlVJ3oHjz2w4om/JoQCxjmXV+SAETC+O2Wo6TYLdy+etbgNofNwk/XL+V4Sze/fPfQ4PZ3DzSyckY2GSG06WeZWEITseOPn1bT1tPPhkvmnLL9/i8sQaH48cv7Bre9e6CRzFQ7y6dnjfm+aU4bVouSGoAQE+Xza94orWPdorwz2lzXzJvC+uXTePjdQ5TVtvOnT6sorWnnyiV5Ib13psu8URoidmwqqWVebhorTuvULchK5W8+M5/N++p5dU8tuytb2birhnWL8rBaRu9fgsCMoFmp5jwMJqOARELYVXmCpk4PVywe/kv9vs8t4oPyJtY/9BEKuGDOJO5cMyuk985KHRinLU1Ayaqtp59th1v4xsVzht1/19rZbNxdw7f+sJP0FBs56U7+4XOLQn5/s6YbkRqASAib9zVgsyguXZA77P7c9BQ2fecirlicx/RJLv7vLStCXuTdYbPgdlhlSugk9u6BBrx+zbpFwxcwHDYLL9yzmm9cNBu3w8bDX11J9hijf4bKcjlMedo8IjUApdRjwOeBBq310mH2K+B/gM8C3cCdWuudkTi3EACb99VxwZzJgyMqhpObkcJDt66Y0PtnucxbtEOYb/O+eqakOTl3lDZ9t9PGfZ9bzH2fWzzu989KtVPb1htOiBMSqRrA48DVo+y/Bpgf/NkA/G+EzisEhxs7OdTYxbpFw5f+IyEj1U6bjAJKSh6vn/cONLJuUS6WENr0JyIz1U6bCX0AEUkAWuv3gZZRDlkP/E4HbAWylFL5kTi3EG+W1QOwboT2/0hId9ro7PNG7f1F7Np2pJmOPu+IzT+RkJZizvVlVB9AAVA55Peq4DYhwrZ5Xz2L8zMozHZF7RxpKTa6+oyfrVGYb/O+elLtVtbOH/uZkYlKc9ro6vMaPt9UzHUCK6U2KKWKlVLFjY2NZocjYlxzZx87jp2IaukfAu27UgNIPlpr3txXz0Xzpww+XBgNaSk2vH5N3zBTSkSTUQmgGpg+5PfC4LYzaK0f0VoXaa2LcnLGfopOJLe39zfg13BllBNAmtNGR68kgGRTWtNOTVvviMOLIyXNGRiPY/Q1ZlQC2AjcrgIuANq01rUGnVsksNdL68nPTGHJtNGn3A1XeoqNzj4ZBZRs3iitw6Lg8oXRG2AAJxNAl8G1zEgNA30auBSYopSqAv4RsANorR8GXiMwBLSCwDDQr0XivCK5tXX38/7
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"plt.plot(time_space(), -1 * saw(time_space()))"
]
},
{
"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",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x1049a7f98>]"
]
},
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"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",
"plt.plot(time_space(), wave)"
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"max: 0.9993055302951397 Hz\n"
]
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x104ac8cc0>]"
]
},
"execution_count": 16,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"max_hz, spectrum = frequency_spectrum(wave)\n",
"print(\"max: {} Hz\".format(max_hz))\n",
"plt.plot(spectrum[:Harmonics], 'x')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Triangle Wave"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x104b1f710>]"
]
},
"execution_count": 17,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"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",
"plt.plot(time_space(), wave)"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"max: 0.9969907724658861 Hz\n"
]
},
{
"data": {
"text/plain": [
"[<matplotlib.lines.Line2D at 0x104bd6e48>]"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "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
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"max_hz, spectrum = frequency_spectrum(wave)\n",
"print(\"max: {} Hz\".format(max_hz))\n",
"plt.plot(spectrum[:Harmonics], 'x')"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"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.6.1"
}
},
"nbformat": 4,
"nbformat_minor": 2
}