{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "later-transformation",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "application/vnd.jupyter.widget-view+json": {
       "model_id": "5eed942c2a5549f8b7c44a9a758f34d8",
       "version_major": 2,
       "version_minor": 0
      },
      "text/plain": [
       "interactive(children=(FloatSlider(value=2.0, continuous_update=False, description='f [kHz]', max=3.0, min=2.0,…"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "from matplotlib.patches import Rectangle\n",
    "from ipywidgets import interact, FloatSlider, Checkbox, Dropdown\n",
    "\n",
    "%matplotlib inline\n",
    "\n",
    "fs = 48e3\n",
    "fs_analog = fs*100\n",
    "\n",
    "def fourier_demo_interactive_fnc(f0, samples, T, zoom):\n",
    "    t = np.arange(fs*T)/fs\n",
    "    t_analog = np.arange(fs_analog*T)/fs_analog\n",
    "    t_analog2 = np.concatenate((t_analog-T, t_analog, t_analog+T))\n",
    "\n",
    "    x = np.sin(2*np.pi*1000*f0*t)\n",
    "\n",
    "    x_analog = np.sin(2*np.pi*1000*f0*t_analog)\n",
    "    x_analog2 = np.concatenate((x_analog, x_analog, x_analog))\n",
    "\n",
    "    fig, ax = plt.subplots(2, 1, figsize=(14,10))\n",
    "    \n",
    "    ax[0].plot(t_analog2*1000, x_analog2)\n",
    "    ax[0].set(ylim=(-1.2, 1.2))\n",
    "    \n",
    "    if samples:\n",
    "        ax[0].plot(t*1000, x, 'o')\n",
    "        ax[0].plot((t-T)*1000, x, 'o', color=(0.5, 0.5, 0.5))\n",
    "        ax[0].plot((t+T)*1000, x, 'o', color=(0.5, 0.5, 0.5))\n",
    "    \n",
    "    if zoom==0:\n",
    "        ax[0].set(xlim=(0, T*1000))\n",
    "    elif zoom==1:\n",
    "        ax[0].set(xlim=(-T*400, T*1400))\n",
    "        ax[0].add_patch(Rectangle((-T*400, -1.2), T*400, 2.4, facecolor=(0.9, 0.9, 0.9)))\n",
    "        ax[0].add_patch(Rectangle((T*1000, -1.2), T*400, 2.4, facecolor=(0.9, 0.9, 0.9)))\n",
    "    elif zoom==2:\n",
    "        ax[0].set(xlim=(-0.4, 0.6))\n",
    "        ax[0].add_patch(Rectangle((-0.4, -1.2), 0.4, 2.4, facecolor=(0.9, 0.9, 0.9)))\n",
    "    elif zoom==3:\n",
    "        ax[0].set(xlim=(T*1000-0.6, T*1000+0.4))\n",
    "        ax[0].add_patch(Rectangle((T*1000, -1.2), 0.4, 2.4, facecolor=(0.9, 0.9, 0.9)))\n",
    "    \n",
    "    X = np.fft.rfft(x)/len(x)*2\n",
    "    f_axis = np.fft.rfftfreq(len(x), 1/fs)\n",
    "\n",
    "    ax[1].plot(f_axis, 20*np.log10(np.abs(X)))\n",
    "    ax[1].set(ylim=(-60, 0))\n",
    "    \n",
    "    ax[0].set(xlabel='Time [ms]')\n",
    "    ax[1].set(xlabel='Frequency [Hz]')\n",
    "\n",
    "interact(fourier_demo_interactive_fnc, \\\n",
    "         T = Dropdown(options=[('1 ms',1e-3), ('10 ms',1e-2)], value=1e-3, description='time window'), \\\n",
    "         f0 = FloatSlider(min=2,max=3,step=0.01, value=2, continuous_update=False, description='f [kHz]'), \\\n",
    "         zoom = Dropdown(options=[('full signal',0), ('full signal + periodized',1), ('signal beginning',2), ('signal end',3)], value=0, description='zoom'), \\\n",
    "         samples = Checkbox(True, description='show samples (fs = 48 kHz)'), \\\n",
    "                  );    \n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "monthly-intelligence",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b55396bc",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
